From 47d5395d24c6f209a758a689bff9a44f68d7397b Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 30 Mar 2014 13:44:28 +0200 Subject: [PATCH 001/312] Added a blockface parameter to the OnProjectileHitBlock hook. --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 4 ++-- src/Bindings/PluginManager.h | 2 +- src/Entities/ProjectileEntity.cpp | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index df0bd4dcc..4144bc734 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, eBlockFace a_Face) = 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 7e69e0f4b..9e989a9e1 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,14 +1108,14 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a -bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile) +bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face) { 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_Face, cLuaState::Return, res); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 59542d23a..e89baaf53 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, eBlockFace a_Face) 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 6a5356c0b..7116a5826 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,7 +1154,7 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti -bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile) +bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face) { HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_BLOCK); if (Plugins == m_Hooks.end()) @@ -1163,7 +1163,7 @@ bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile } for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnProjectileHitBlock(a_Projectile)) + if ((*itr)->OnProjectileHitBlock(a_Projectile, a_Face)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 512bc1351..89a2170df 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, eBlockFace a_Face); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index a9735a53c..37964d102 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -67,7 +67,7 @@ protected: eBlockFace Face; if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face)) { - if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile)) + if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, Face)) { return false; } From 66f1bb7b677324dd59265b7b0776490caa661bcc Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 30 Mar 2014 14:04:44 +0200 Subject: [PATCH 002/312] Added a BlockHitPos parameter to OnProjectileHitBlock --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 4 ++-- src/Bindings/PluginManager.h | 2 +- src/Entities/ProjectileEntity.cpp | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 4144bc734..9c2b59609 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, eBlockFace a_Face) = 0; + virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, eBlockFace a_Face, 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 9e989a9e1..a89cfc82c 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,14 +1108,14 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a -bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face) +bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face, 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, a_Face, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Projectile, a_Face, a_BlockHitPos, cLuaState::Return, res); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index e89baaf53..2e757f9dd 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, eBlockFace a_Face) override; + virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, eBlockFace a_Face, 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 7116a5826..0aa52e97e 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,7 +1154,7 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti -bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face) +bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face, Vector3d * a_BlockHitPos) { HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_BLOCK); if (Plugins == m_Hooks.end()) @@ -1163,7 +1163,7 @@ bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile } for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnProjectileHitBlock(a_Projectile, a_Face)) + if ((*itr)->OnProjectileHitBlock(a_Projectile, a_Face, a_BlockHitPos)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 89a2170df..5fdbaac1c 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, eBlockFace a_Face); + bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, eBlockFace a_Face, 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/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 37964d102..72ebf5775 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -67,12 +67,12 @@ protected: eBlockFace Face; if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face)) { - if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, Face)) + Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; + if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, Face, &Intersection)) { return false; } - Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; m_Projectile->OnHitSolidBlock(Intersection, Face); return true; } From 36e1e57d038eda0c183f616f2b45d2ae4733e27c Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 30 Mar 2014 17:21:13 +0200 Subject: [PATCH 003/312] Using recommendations (I think) --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 2 +- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 2 +- src/Bindings/PluginManager.h | 2 +- src/Entities/ProjectileEntity.cpp | 3 ++- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 9c2b59609..a6f91382c 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, eBlockFace a_Face, Vector3d * a_BlockHitPos) = 0; + virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, eBlockFace a_Face, const Vector3i * 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 a89cfc82c..97f78351b 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,7 +1108,7 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a -bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face, Vector3d * a_BlockHitPos) +bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face, const Vector3i * a_BlockHitPos) { cCSLock Lock(m_CriticalSection); bool res = false; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 2e757f9dd..627aa3cc8 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, eBlockFace a_Face, Vector3d * a_BlockHitPos) override; + virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, eBlockFace a_Face, const Vector3i * 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 0aa52e97e..a5c904a77 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,7 +1154,7 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti -bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face, Vector3d * a_BlockHitPos) +bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face, const Vector3i * a_BlockHitPos) { HookMap::iterator Plugins = m_Hooks.find(HOOK_PROJECTILE_HIT_BLOCK); if (Plugins == m_Hooks.end()) diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 5fdbaac1c..35755459a 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, eBlockFace a_Face, Vector3d * a_BlockHitPos); + bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, eBlockFace a_Face, const Vector3i * 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/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 72ebf5775..7a869a957 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -68,7 +68,8 @@ protected: if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face)) { Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; - if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, Face, &Intersection)) + const Vector3i BlockHitPos = Vector3i(Intersection); + if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, Face, &BlockHitPos)) { return false; } From e40f9d6e5b93e840e3d67e79f5ba49da1fbb75f0 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 26 Apr 2014 10:50:23 -0700 Subject: [PATCH 004/312] Implemented Chunk Sparsing with segments --- src/BlockArea.cpp | 170 ++++++------- src/BlockArea.h | 5 +- src/Chunk.cpp | 186 +++----------- src/Chunk.h | 32 +-- src/ChunkBuffer.cpp | 146 +++++++++++ src/ChunkBuffer.h | 310 ++++++++++++++++++++++++ src/ChunkDef.h | 100 +------- src/ChunkMap.cpp | 16 +- src/ChunkSender.h | 1 + src/Entities/FallingBlock.cpp | 5 +- src/LightingThread.cpp | 11 +- src/MobProximityCounter.cpp | 3 +- src/Simulator/FireSimulator.cpp | 10 +- src/WorldStorage/NBTChunkSerializer.cpp | 3 +- src/WorldStorage/NBTChunkSerializer.h | 4 +- src/WorldStorage/WSSCompact.cpp | 10 +- src/WorldStorage/WSSCompact.h | 3 +- 17 files changed, 612 insertions(+), 403 deletions(-) create mode 100644 src/ChunkBuffer.cpp create mode 100644 src/ChunkBuffer.h diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 40cca8882..b4b519bc7 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 "ChunkBuffer.h" @@ -1909,116 +1909,88 @@ bool cBlockArea::cChunkReader::Coords(int a_ChunkX, int a_ChunkZ) -void cBlockArea::cChunkReader::BlockTypes(const BLOCKTYPE * a_BlockTypes) +void cBlockArea::cChunkReader::ChunkBuffer(const cChunkBuffer & 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) - // 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; - int SizeZ = cChunkDef::Width; - int OffX, OffZ; - int BaseX, BaseZ; - OffX = m_CurrentChunkX * cChunkDef::Width - m_Origin.x; - if (OffX < 0) - { - BaseX = -OffX; - SizeX += OffX; // SizeX is decreased, OffX is negative - OffX = 0; - } - else - { - BaseX = 0; - } - OffZ = m_CurrentChunkZ * cChunkDef::Width - m_Origin.z; - if (OffZ < 0) - { - BaseZ = -OffZ; - SizeZ += OffZ; // SizeZ is decreased, OffZ is negative - OffZ = 0; - } - else - { - BaseZ = 0; - } - // If the chunk extends beyond the area in the X or Z axis, cut off the Size: - if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_Origin.x + m_Area.m_Size.x) - { - SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_Origin.x + m_Area.m_Size.x); - } - if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_Origin.z + m_Area.m_Size.z) - { - SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z); - } - - for (int y = 0; y < SizeY; y++) - { - int ChunkY = MinY + y; - int AreaY = y; - for (int z = 0; z < SizeZ; z++) + { // BlockTypes + if (!(m_Area.m_BlockTypes == NULL)) { - int ChunkZ = BaseZ + z; - int AreaZ = OffZ + z; - for (int x = 0; x < SizeX; x++) + int SizeY = m_Area.m_Size.y; + int MinY = m_Origin.y; + + // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) + // OffX, OffZ are the offsets of the current chunk data from the area origin + // BaseX, BaseZ are the offsets of the area data within the current chunk from the chunk borders + int SizeX = cChunkDef::Width; + int SizeZ = cChunkDef::Width; + int OffX, OffZ; + int BaseX, BaseZ; + OffX = m_CurrentChunkX * cChunkDef::Width - m_Origin.x; + if (OffX < 0) { - 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 -} + BaseX = -OffX; + SizeX += OffX; // SizeX is decreased, OffX is negative + OffX = 0; + } + else + { + BaseX = 0; + } + OffZ = m_CurrentChunkZ * cChunkDef::Width - m_Origin.z; + if (OffZ < 0) + { + BaseZ = -OffZ; + SizeZ += OffZ; // SizeZ is decreased, OffZ is negative + OffZ = 0; + } + else + { + BaseZ = 0; + } + // If the chunk extends beyond the area in the X or Z axis, cut off the Size: + if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_Origin.x + m_Area.m_Size.x) + { + SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_Origin.x + m_Area.m_Size.x); + } + if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_Origin.z + m_Area.m_Size.z) + { + SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z); + } - - - - -void cBlockArea::cChunkReader::BlockMeta(const NIBBLETYPE * a_BlockMetas) -{ - if (m_Area.m_BlockMetas == NULL) - { - // Don't want metas - return; + for (int y = 0; y < SizeY; y++) + { + int ChunkY = MinY + y; + int AreaY = y; + for (int z = 0; z < SizeZ; z++) + { + int ChunkZ = BaseZ + z; + int AreaZ = OffZ + z; + for (int x = 0; x < SizeX; x++) + { + int ChunkX = BaseX + x; + int AreaX = OffX + x; + m_Area.m_BlockTypes[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetBlock(ChunkX, ChunkY, ChunkZ); + } // 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) + if (m_Area.m_BlockMetas) { - // Don't want light - return; + a_BlockBuffer.CopyMeta(m_Area.m_BlockMetas); } - CopyNibbles(m_Area.m_BlockLight, a_BlockLight); -} - - - - -void cBlockArea::cChunkReader::BlockSkyLight(const NIBBLETYPE * a_BlockSkyLight) -{ - if (m_Area.m_BlockSkyLight == NULL) + if (m_Area.m_BlockLight) { - // Don't want skylight - return; + a_BlockBuffer.CopyLight(m_Area.m_BlockLight); } - CopyNibbles(m_Area.m_BlockSkyLight, a_BlockSkyLight); -} + if (m_Area.m_BlockSkyLight) + { + a_BlockBuffer.CopySkyLight(m_Area.m_BlockSkyLight); + } + +} diff --git a/src/BlockArea.h b/src/BlockArea.h index c48175b8c..d17a68fbb 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -317,10 +317,7 @@ protected: // 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 void ChunkBuffer (const cChunkBuffer & a_BlockTypes) override; } ; typedef NIBBLETYPE * NIBBLEARRAY; diff --git a/src/Chunk.cpp b/src/Chunk.cpp index ee1531b5c..171f329fb 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -241,23 +241,9 @@ void cChunk::GetAllData(cChunkDataCallback & a_Callback) a_Callback.HeightMap (&m_HeightMap); a_Callback.BiomeData (&m_BiomeMap); - std::vector Blocks = m_BlockTypes; - Blocks.resize(NumBlocks); - a_Callback.BlockTypes (&Blocks[0]); - - std::vector Metas = m_BlockMeta; - Metas.resize(NumBlocks / 2); - a_Callback.BlockMeta (&Metas[0]); - a_Callback.LightIsValid (m_IsLightValid); - std::vector BlockLights = m_BlockLight; - BlockLights.resize(NumBlocks / 2); - a_Callback.BlockLight (&BlockLights[0]); - - std::vector BlockSkyLights = m_BlockSkyLight; - BlockSkyLights.resize(NumBlocks / 2, 0xff); - a_Callback.BlockSkyLight(&BlockSkyLights[0]); + a_Callback.ChunkBuffer (m_ChunkBuffer); for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) { @@ -296,48 +282,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_ChunkBuffer.SetBlocks (a_BlockTypes); + m_ChunkBuffer.SetMeta (a_BlockMeta); + m_ChunkBuffer.SetLight (a_BlockLight); + m_ChunkBuffer.SetSkyLight (a_BlockSkyLight); m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL); @@ -378,39 +326,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 - bool FoundNonEmpty = false; - int IdxWhereNonEmptyStarts = 0; - m_BlockLight.clear(); + m_ChunkBuffer.SetLight (a_BlockLight); - for (int Idx = (NumBlocks / 2) - 1; Idx >= 0; Idx--) - { - if (a_BlockLight[Idx] != 0) - { - FoundNonEmpty = true; - IdxWhereNonEmptyStarts = Idx; - break; - } - } - m_BlockLight.insert(m_BlockLight.end(), &a_BlockLight[0], &a_BlockLight[IdxWhereNonEmptyStarts + 1]); - } - - { // Compress skylight - bool FoundNonEmpty = false; - int IdxWhereNonEmptyStarts = 0; - m_BlockSkyLight.clear(); - - for (int Idx = (NumBlocks / 2) - 1; Idx >= 0; Idx--) - { - if (a_SkyLight[Idx] != 0xff) - { - FoundNonEmpty = true; - IdxWhereNonEmptyStarts = Idx; - break; - } - } - m_BlockSkyLight.insert(m_BlockSkyLight.end(), &a_SkyLight[0], &a_SkyLight[IdxWhereNonEmptyStarts + 1]); - } + m_ChunkBuffer.SetSkyLight (a_SkyLight); m_IsLightValid = true; } @@ -421,10 +339,7 @@ void cChunk::SetLight( void cChunk::GetBlockTypes(BLOCKTYPE * a_BlockTypes) { - std::vector Blocks = m_BlockTypes; - Blocks.resize(NumBlocks); - - memcpy(a_BlockTypes, &Blocks[0], NumBlocks); + m_ChunkBuffer.CopyBlocks(a_BlockTypes); } @@ -710,8 +625,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()); @@ -836,19 +750,18 @@ void cChunk::CheckBlocks() { return; } - std::vector ToTickBlocks; + std::vector ToTickBlocks; std::swap(m_ToTickBlocks, ToTickBlocks); cChunkInterface ChunkInterface(m_World->GetChunkMap()); cBlockInServerPluginInterface PluginInterface(*m_World); - for (std::vector::const_iterator itr = ToTickBlocks.begin(), end = ToTickBlocks.end(); itr != end; ++itr) + for (std::vector::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[] } @@ -891,8 +804,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 @@ -1284,9 +1196,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; } @@ -1490,11 +1401,9 @@ 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) { FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta); - - const int index = MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); // 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: @@ -1557,7 +1466,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)); } @@ -1595,9 +1504,8 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT 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_ChunkBuffer.GetMeta(a_RelX, a_RelY, a_RelZ); if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta)) { return; @@ -1605,11 +1513,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT MarkDirty(); - if (m_BlockTypes.empty() || ((size_t)index > m_BlockTypes.size() - 1) /* Vector starts from zero, .size() starts from 1 */) - { - m_BlockTypes.resize(index + 1); - } - m_BlockTypes[index] = a_BlockType; + m_ChunkBuffer.SetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType); // The client doesn't need to distinguish between stationary and nonstationary fluids: if ( @@ -1625,7 +1529,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT 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_ChunkBuffer.SetMeta(a_RelX, a_RelY, a_RelZ, a_BlockMeta); // ONLY recalculate lighting if it's necessary! if ( @@ -1648,7 +1552,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT { 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; break; @@ -1665,18 +1569,16 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT 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) @@ -2535,27 +2437,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 (m_BlockTypes.empty() || ((size_t)a_BlockIdx > m_BlockTypes.size() - 1) /* Vector starts from zero, .size() starts from 1 */) - { - return E_BLOCK_AIR; - } - - return m_BlockTypes[a_BlockIdx]; + return m_ChunkBuffer.GetBlock(a_RelX, a_RelY, a_RelZ); } @@ -2564,9 +2446,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_ChunkBuffer.GetMeta(a_RelX, a_RelY, a_RelZ); } @@ -2575,11 +2456,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_ChunkBuffer.GetMeta(a_RelX, a_RelY, a_RelZ); + a_SkyLight = m_ChunkBuffer.GetSkyLight(a_RelX, a_RelY, a_RelZ); + a_BlockLight = m_ChunkBuffer.GetBlockLight(a_RelX, a_RelY, a_RelZ); } diff --git a/src/Chunk.h b/src/Chunk.h index 9100eec58..ea3e035ad 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -3,6 +3,7 @@ #include "Entities/Entity.h" #include "ChunkDef.h" +#include "ChunkBuffer.h" #include "Simulator/FireSimulator.h" #include "Simulator/SandSimulator.h" @@ -66,6 +67,7 @@ public: cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP // Neighbor chunks ); + cChunk(cChunk& other); ~cChunk(); bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk block data is valid (loaded / generated) @@ -154,7 +156,7 @@ public: 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. 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 +322,17 @@ public: m_BlockTickZ = a_RelZ; } - inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); } - inline NIBBLETYPE GetMeta(int a_BlockIdx) const {return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); } - inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ, a_Meta); } - inline void SetMeta(int a_BlockIdx, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_BlockIdx, a_Meta); } + inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const + { + return m_ChunkBuffer.GetMeta(a_RelX, a_RelY, a_RelZ); + } + inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) + { + m_ChunkBuffer.SetMeta(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_ChunkBuffer.GetBlockLight(a_RelX, a_RelY, a_RelZ); } + inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkBuffer.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; @@ -403,8 +407,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 m_ToTickBlocks; - sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients + std::vector 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,11 +424,7 @@ private: cWorld * m_World; cChunkMap * m_ChunkMap; - // TODO: Make these pointers and don't allocate what isn't needed - std::vector m_BlockTypes; - std::vector m_BlockMeta; - std::vector m_BlockLight; - std::vector m_BlockSkyLight; + cChunkBuffer m_ChunkBuffer; cChunkDef::HeightMap m_HeightMap; cChunkDef::BiomeMap m_BiomeMap; diff --git a/src/ChunkBuffer.cpp b/src/ChunkBuffer.cpp new file mode 100644 index 000000000..8e87d3049 --- /dev/null +++ b/src/ChunkBuffer.cpp @@ -0,0 +1,146 @@ + +#include "Globals.h" +#include "ChunkBuffer.h" + +cChunkBuffer cChunkBuffer::Copy() const +{ + cChunkBuffer copy; + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + if(m_Sections[i]) + { + copy.m_Sections[i] = Allocate(); + *copy.m_Sections[i] = *m_Sections[i]; + } + } + return copy; +} + + + + + +void cChunkBuffer::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) const +{ + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; + if (a_Idx > 0) a_Idx = a_Idx > length ? a_Idx - length : 0; + if (a_Idx == 0) + { + size_t tocopy = length > segment_length ? segment_length : length; + length -= tocopy; + memcpy(&a_dest[i * segment_length], &m_Sections[i]->m_BlockTypes, sizeof(BLOCKTYPE) * length); + } + } +} + + + + + +void cChunkBuffer::CopyMeta(NIBBLETYPE * a_dest) const +{ + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + memcpy(&a_dest[i * segment_length], &m_Sections[i]->m_BlockMeta, sizeof(NIBBLETYPE) * segment_length); + } +} + + + + + +void cChunkBuffer::CopyLight(NIBBLETYPE * a_dest) const +{ + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + memcpy(&a_dest[i * segment_length], &m_Sections[i]->m_BlockLight, sizeof(NIBBLETYPE) * segment_length); + } +} + + + + + +void cChunkBuffer::CopySkyLight(NIBBLETYPE * a_dest) const +{ + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + memcpy(&a_dest[i * segment_length], &m_Sections[i]->m_BlockSkyLight, sizeof(NIBBLETYPE) * segment_length); + } +} + + + + + +void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) +{ + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + if (m_Sections[i]) + { + memcpy(&m_Sections[i]->m_BlockTypes, &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length); + } + } +} + + + + +void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) +{ + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + if (m_Sections[i]) + { + memcpy(&m_Sections[i]->m_BlockMeta, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); + } + } +} + + + + +void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) +{ + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + if (m_Sections[i]) + { + memcpy(&m_Sections[i]->m_BlockLight, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); + } + } +} + + + + +void cChunkBuffer::SetSkyLight (const NIBBLETYPE * a_src) +{ + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + if (m_Sections[i]) + { + memcpy(&m_Sections[i]->m_BlockSkyLight, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); + } + } +} + + + + + +cChunkBuffer::sChunkSection * cChunkBuffer::Allocate() const +{ + // TODO: use a allocation pool + return new cChunkBuffer::sChunkSection; +} diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h new file mode 100644 index 000000000..44e447c82 --- /dev/null +++ b/src/ChunkBuffer.h @@ -0,0 +1,310 @@ + +#pragma once + +#define CHUNK_SECTION_HEIGHT 16 +#define CHUNK_SECTION_NUM (256 / CHUNK_SECTION_HEIGHT) + +#if __cplusplus < 201103L +// auto_ptr style interface for memory management +#else +// unique_ptr style interface for memory management +#endif + +class cChunkBuffer +{ +public: + + cChunkBuffer() + #if __cplusplus < 201103L + // auto_ptr style interface for memory management + : IsOwner(true) + #endif + { + memset(m_Sections, 0, sizeof(m_Sections)); + } + ~cChunkBuffer() + { + #if __cplusplus < 201103L + // auto_ptr style interface for memory management + if(!IsOwner) return; + #endif + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + if(m_Sections[i]) delete m_Sections[i]; + } + } + + #if __cplusplus < 201103L + // auto_ptr style interface for memory management + cChunkBuffer(cChunkBuffer& other) : + IsOwner(true); + { + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + m_Sections[i] = other.m_Sections[i]; + } + other.IsOwner = false; + } + void operator=(cChunkBuffer& other) + { + if(IsOwner) + { + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + if(m_Sections[i]) delete m_Sections[i]; + } + } + IsOwner = true; + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + m_Sections[i] = other.m_Sections[i]; + } + other.IsOwner = false; + } + #else + // unique_ptr style interface for memory management + cChunkBuffer(cChunkBuffer&& other) + { + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + m_Sections[i] = other.m_Sections[i]; + } + } + + void operator=(cChunkBuffer&& other) + { + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + if(m_Sections[i]) delete m_Sections[i]; + m_Sections[i] = other.m_Sections[i]; + } + } + #endif + + BLOCKTYPE 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 / CHUNK_SECTION_HEIGHT; + if(m_Sections[Section]) + { + int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * CHUNK_SECTION_HEIGHT), a_Z); + return m_Sections[Section]->m_BlockTypes[Index]; + } + else + { + return 0; + } + } + + void 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(!"cChunkBuffer::SetMeta(): index out of range!"); + return; + } + + int Section = a_RelY / CHUNK_SECTION_HEIGHT; + if(!m_Sections[Section]) + { + m_Sections[Section] = Allocate(); + if(!m_Sections[Section]) + { + ASSERT("Failed to allocate a new section in Chunkbuffer"); + return; + } + } + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + m_Sections[Section]->m_BlockTypes[Index] = a_Block; + } + + NIBBLETYPE 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 / CHUNK_SECTION_HEIGHT; + if(m_Sections[Section]) + { + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + return (m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + } + else + { + return 0; + } + } + ASSERT(!"cChunkBuffer::GetMeta(): coords out of chunk range!"); + return 0; + } + + void 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(!"cChunkBuffer::SetMeta(): index out of range!"); + return; + } + + int Section = a_RelY / CHUNK_SECTION_HEIGHT; + if(!m_Sections[Section]) + { + m_Sections[Section] = Allocate(); + if(!m_Sections[Section]) + { + ASSERT("Failed to allocate a new section in Chunkbuffer"); + return; + } + } + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + m_Sections[Section]->m_BlockMeta[Index / 2] = static_cast( + (m_Sections[Section]->m_BlockMeta[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble + ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set + ); + } + + NIBBLETYPE 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 / CHUNK_SECTION_HEIGHT; + if(m_Sections[Section]) + { + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + } + else + { + return 0; + } + } + ASSERT(!"cChunkBuffer::GetMeta(): coords out of chunk range!"); + return 0; + } + + NIBBLETYPE 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 / CHUNK_SECTION_HEIGHT; + if(m_Sections[Section]) + { + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + } + else + { + return 0xFF; + } + } + ASSERT(!"cChunkBuffer::GetMeta(): coords out of chunk range!"); + return 0; + } + + cChunkBuffer Copy() const; + void CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx = 0, size_t length = cChunkDef::NumBlocks) const; + void CopyMeta (NIBBLETYPE * a_dest) const; + void CopyLight (NIBBLETYPE * a_dest) const; + void CopySkyLight (NIBBLETYPE * a_dest) const; + + void SetBlocks (const BLOCKTYPE * a_src); + void SetMeta (const NIBBLETYPE * a_src); + void SetLight (const NIBBLETYPE * a_src); + void SetSkyLight (const NIBBLETYPE * a_src); + +private: + + #if __cplusplus < 201103L + // auto_ptr style interface for memory management + bool IsOwner; + #endif + + struct sChunkSection { + BLOCKTYPE m_BlockTypes [CHUNK_SECTION_HEIGHT * 16 * 16] ; + NIBBLETYPE m_BlockMeta [CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; + NIBBLETYPE m_BlockLight [CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; + NIBBLETYPE m_BlockSkyLight[CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; + }; + + sChunkSection *m_Sections[CHUNK_SECTION_NUM]; + + sChunkSection * Allocate() const; +}; + + + + +/** A simple implementation of the cChunkDataCallback interface that collects all block data into a buffer +*/ +class cChunkBufferCollector : + public cChunkDataCallback +{ +public: + + cChunkBuffer m_BlockData; + +protected: + + virtual void ChunkBuffer(const cChunkBuffer & 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 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 ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override + { + a_ChunkBuffer.CopyBlocks(m_BlockData); + a_ChunkBuffer.CopyMeta(m_BlockData + cChunkDef::NumBlocks); + a_ChunkBuffer.CopyLight(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 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 ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override + { + a_ChunkBuffer.CopyBlocks(m_BlockTypes); + a_ChunkBuffer.CopyMeta(m_BlockMetas); + a_ChunkBuffer.CopyLight(m_BlockLight); + a_ChunkBuffer.CopySkyLight(m_BlockSkyLight); + } +} ; + + + + diff --git a/src/ChunkDef.h b/src/ChunkDef.h index bb9f14bbe..a5eccc9d6 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -366,6 +366,7 @@ public: +class cChunkBuffer; /** Interface class used for getting data out of a chunk using the GetAllData() function. @@ -390,20 +391,11 @@ public: /// 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 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 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 once to export block info + virtual void ChunkBuffer (const cChunkBuffer & a_Buffer) {UNUSED(a_Buffer); }; /// Called for each entity in the chunk virtual void Entity(cEntity * a_Entity) {UNUSED(a_Entity); }; @@ -416,88 +408,6 @@ public: -/** 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 e695f0ab2..2b47f25f8 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -219,9 +219,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 +241,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 +262,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; } @@ -1486,9 +1483,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; } diff --git a/src/ChunkSender.h b/src/ChunkSender.h index a26f764a7..81b298a55 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 "ChunkBuffer.h" diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp index a66c7e4ae..e57c45eaf 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/LightingThread.cpp b/src/LightingThread.cpp index 302473d71..56d5dba22 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -18,20 +18,17 @@ class cReader : public cChunkDataCallback { - virtual void BlockTypes(const BLOCKTYPE * a_Type) override + virtual void ChunkBuffer(const cChunkBuffer & 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++) { for (int z = 0; z < cChunkDef::Width; z++) { - OutputRows[OutputIdx] = InputRows[InputIdx++]; + a_ChunkBuffer.CopyBlocks(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 diff --git a/src/MobProximityCounter.cpp b/src/MobProximityCounter.cpp index 6c44ea458..e7493dd0f 100644 --- a/src/MobProximityCounter.cpp +++ b/src/MobProximityCounter.cpp @@ -24,7 +24,8 @@ 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; + ASSERT(false); + //it->second.m_Chunk = a_Chunk; } } diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index 470dfc791..4c1008897 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/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 415693ae2..10acfb537 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -692,10 +692,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..6da2bc6dd 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -9,7 +9,7 @@ #pragma once -#include "../ChunkDef.h" +#include "../ChunkBuffer.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/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index bb9d4b9e6..b44dd02c5 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 4df146ec3..49a897984 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 "ChunkBuffer.h" @@ -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; } ; From dcb2a590e364301aa1919546ad33a33e5dc34042 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 27 Apr 2014 06:45:33 -0700 Subject: [PATCH 005/312] Fixed bad merge --- src/Chunk.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 5a82ca66a..6b0058303 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1468,7 +1468,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)); } @@ -1531,7 +1531,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT 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_ChunkBuffer.SetMeta(a_RelX, a_RelY, a_RelZ, a_BlockMeta); // ONLY recalculate lighting if it's necessary! if ( @@ -1554,7 +1554,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT { 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; break; @@ -1570,19 +1570,16 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT 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) @@ -2460,11 +2457,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_ChunkBuffer.GetMeta(a_RelX, a_RelY, a_RelZ); + a_SkyLight = m_ChunkBuffer.GetSkyLight(a_RelX, a_RelY, a_RelZ); + a_BlockLight = m_ChunkBuffer.GetBlockLight(a_RelX, a_RelY, a_RelZ); } From e3bdc81ca04fbad284eb0c3b53678f0fb357eb64 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 27 Apr 2014 06:46:13 -0700 Subject: [PATCH 006/312] Fixed MobProximity Counter to remove chunk copys --- src/MobProximityCounter.cpp | 5 ++--- src/MobProximityCounter.h | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/MobProximityCounter.cpp b/src/MobProximityCounter.cpp index c7e91e18b..ce20bf56b 100644 --- a/src/MobProximityCounter.cpp +++ b/src/MobProximityCounter.cpp @@ -24,8 +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; - ASSERT(false); - //it->second.m_Chunk = a_Chunk; + it->second.m_Chunk = &a_Chunk; } } @@ -37,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 { From 2730a41946b5236894d65ec9cc001ed41b6a5589 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 27 Apr 2014 07:10:30 -0700 Subject: [PATCH 007/312] Fixed issues with gcc --- src/ChunkBuffer.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h index 44e447c82..a6a6da013 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -36,8 +36,8 @@ public: #if __cplusplus < 201103L // auto_ptr style interface for memory management - cChunkBuffer(cChunkBuffer& other) : - IsOwner(true); + cChunkBuffer(const cChunkBuffer& other) : + IsOwner(true) { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -45,7 +45,8 @@ public: } other.IsOwner = false; } - void operator=(cChunkBuffer& other) + + void operator=(const cChunkBuffer& other) { if(IsOwner) { @@ -63,7 +64,7 @@ public: } #else // unique_ptr style interface for memory management - cChunkBuffer(cChunkBuffer&& other) + cChunkBuffer(const cChunkBuffer&& other) { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -71,7 +72,7 @@ public: } } - void operator=(cChunkBuffer&& other) + void operator=(const cChunkBuffer&& other) { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -225,7 +226,7 @@ private: #if __cplusplus < 201103L // auto_ptr style interface for memory management - bool IsOwner; + mutable bool IsOwner; #endif struct sChunkSection { From 48a2488477023b5427381863585fd1448743d32e Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 27 Apr 2014 07:38:16 -0700 Subject: [PATCH 008/312] Added other half of implementation --- src/ChunkBuffer.cpp | 147 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 133 insertions(+), 14 deletions(-) diff --git a/src/ChunkBuffer.cpp b/src/ChunkBuffer.cpp index 8e87d3049..7946fba1e 100644 --- a/src/ChunkBuffer.cpp +++ b/src/ChunkBuffer.cpp @@ -22,7 +22,7 @@ cChunkBuffer cChunkBuffer::Copy() const void cChunkBuffer::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) const { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; if (a_Idx > 0) a_Idx = a_Idx > length ? a_Idx - length : 0; @@ -30,7 +30,22 @@ void cChunkBuffer::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length { size_t tocopy = length > segment_length ? segment_length : length; length -= tocopy; - memcpy(&a_dest[i * segment_length], &m_Sections[i]->m_BlockTypes, sizeof(BLOCKTYPE) * length); + if(m_Sections[i]) + { + memcpy( + &a_dest[i * segment_length], + &m_Sections[i]->m_BlockTypes, + sizeof(BLOCKTYPE) * length + ); + } + else + { + memset( + &a_dest[i * segment_length], + 0, + sizeof(BLOCKTYPE) * length + ); + } } } } @@ -41,10 +56,24 @@ void cChunkBuffer::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length void cChunkBuffer::CopyMeta(NIBBLETYPE * a_dest) const { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - memcpy(&a_dest[i * segment_length], &m_Sections[i]->m_BlockMeta, sizeof(NIBBLETYPE) * segment_length); + if(m_Sections[i]) + { + memcpy( + &a_dest[i * segment_length], + &m_Sections[i]->m_BlockMeta, + sizeof(NIBBLETYPE) * segment_length); + } + else + { + memset( + &a_dest[i * segment_length], + 0, + sizeof(BLOCKTYPE) * segment_length + ); + } } } @@ -54,10 +83,25 @@ void cChunkBuffer::CopyMeta(NIBBLETYPE * a_dest) const void cChunkBuffer::CopyLight(NIBBLETYPE * a_dest) const { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - memcpy(&a_dest[i * segment_length], &m_Sections[i]->m_BlockLight, sizeof(NIBBLETYPE) * segment_length); + if(m_Sections[i]) + { + memcpy( + &a_dest[i * segment_length], + &m_Sections[i]->m_BlockLight, + sizeof(NIBBLETYPE) * segment_length + ); + } + else + { + memset( + &a_dest[i * segment_length], + 0, + sizeof(BLOCKTYPE) * segment_length + ); + } } } @@ -67,10 +111,25 @@ void cChunkBuffer::CopyLight(NIBBLETYPE * a_dest) const void cChunkBuffer::CopySkyLight(NIBBLETYPE * a_dest) const { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - memcpy(&a_dest[i * segment_length], &m_Sections[i]->m_BlockSkyLight, sizeof(NIBBLETYPE) * segment_length); + if(m_Sections[i]) + { + memcpy( + &a_dest[i * segment_length], + &m_Sections[i]->m_BlockSkyLight, + sizeof(NIBBLETYPE) * segment_length + ); + } + else + { + memset( + &a_dest[i * segment_length], + 0xFF, + sizeof(BLOCKTYPE) * segment_length + ); + } } } @@ -80,13 +139,28 @@ void cChunkBuffer::CopySkyLight(NIBBLETYPE * a_dest) const void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i]) { memcpy(&m_Sections[i]->m_BlockTypes, &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length); } + else + { + size_t j = 0; + // do nothing whilst 0 + for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); + if (j != segment_length) + { + m_Sections[i] = Allocate(); + memcpy( + &m_Sections[i]->m_BlockTypes, + &a_src[i * segment_length], + sizeof(BLOCKTYPE) * segment_length + ); + } + } } } @@ -95,13 +169,28 @@ void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i]) { memcpy(&m_Sections[i]->m_BlockMeta, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); } + else + { + size_t j = 0; + // do nothing whilst 0 + for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); + if (j != segment_length) + { + m_Sections[i] = Allocate(); + memcpy( + &m_Sections[i]->m_BlockTypes, + &a_src[i * segment_length], + sizeof(BLOCKTYPE) * segment_length + ); + } + } } } @@ -110,14 +199,29 @@ void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i]) { memcpy(&m_Sections[i]->m_BlockLight, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); } - } + else + { + size_t j = 0; + // do nothing whilst 0 + for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); + if (j != segment_length) + { + m_Sections[i] = Allocate(); + memcpy( + &m_Sections[i]->m_BlockTypes, + &a_src[i * segment_length], + sizeof(BLOCKTYPE) * segment_length + ); + } + } + } } @@ -125,14 +229,29 @@ void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) void cChunkBuffer::SetSkyLight (const NIBBLETYPE * a_src) { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i]) { memcpy(&m_Sections[i]->m_BlockSkyLight, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); } - } + else + { + size_t j = 0; + // do nothing whilst 0 + for (; j < segment_length && a_src[i * segment_length + j] == 0xFF; j++); + if (j != segment_length) + { + m_Sections[i] = Allocate(); + memcpy( + &m_Sections[i]->m_BlockTypes, + &a_src[i * segment_length], + sizeof(BLOCKTYPE) * segment_length + ); + } + } + } } From d412630904c1de6c0d9ef00fbc75b5558f931e8b Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 27 Apr 2014 08:11:56 -0700 Subject: [PATCH 009/312] Fixed a couple of segfaults and made Free a seperate function --- src/ChunkBuffer.cpp | 38 +++++++++++++++++++++++++++++++++++--- src/ChunkBuffer.h | 7 ++++--- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/ChunkBuffer.cpp b/src/ChunkBuffer.cpp index 7946fba1e..a41b8f61a 100644 --- a/src/ChunkBuffer.cpp +++ b/src/ChunkBuffer.cpp @@ -160,6 +160,11 @@ void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) sizeof(BLOCKTYPE) * segment_length ); } + else + { + Free(m_Sections[i]); + m_Sections[i] = 0; + } } } } @@ -185,11 +190,16 @@ void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) { m_Sections[i] = Allocate(); memcpy( - &m_Sections[i]->m_BlockTypes, + &m_Sections[i]->m_BlockMeta, &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); } + else + { + Free(m_Sections[i]); + m_Sections[i] = 0; + } } } } @@ -199,6 +209,7 @@ void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) { + if (!a_src) return; for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; @@ -215,11 +226,16 @@ void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) { m_Sections[i] = Allocate(); memcpy( - &m_Sections[i]->m_BlockTypes, + &m_Sections[i]->m_BlockLight, &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); } + else + { + Free(m_Sections[i]); + m_Sections[i] = 0; + } } } } @@ -229,6 +245,7 @@ void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) void cChunkBuffer::SetSkyLight (const NIBBLETYPE * a_src) { + if (!a_src) return; for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; @@ -245,11 +262,16 @@ void cChunkBuffer::SetSkyLight (const NIBBLETYPE * a_src) { m_Sections[i] = Allocate(); memcpy( - &m_Sections[i]->m_BlockTypes, + &m_Sections[i]->m_BlockSkyLight, &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); } + else + { + Free(m_Sections[i]); + m_Sections[i] = 0; + } } } } @@ -263,3 +285,13 @@ cChunkBuffer::sChunkSection * cChunkBuffer::Allocate() const // TODO: use a allocation pool return new cChunkBuffer::sChunkSection; } + + + +void cChunkBuffer::Free(cChunkBuffer::sChunkSection * ptr) const +{ + delete ptr; +} + + + diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h index a6a6da013..c23f8971d 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -30,7 +30,7 @@ public: #endif for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i]) delete m_Sections[i]; + if(m_Sections[i]) Free(m_Sections[i]);; } } @@ -52,7 +52,7 @@ public: { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i]) delete m_Sections[i]; + if(m_Sections[i]) Free(m_Sections[i]);; } } IsOwner = true; @@ -76,7 +76,7 @@ public: { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i]) delete m_Sections[i]; + if(m_Sections[i]) Free(m_Sections[i]);; m_Sections[i] = other.m_Sections[i]; } } @@ -239,6 +239,7 @@ private: sChunkSection *m_Sections[CHUNK_SECTION_NUM]; sChunkSection * Allocate() const; + void Free(sChunkSection * ptr) const; }; From 6f1fea759e3595d5538330ecf8f05b8edcf0882e Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 27 Apr 2014 08:14:56 -0700 Subject: [PATCH 010/312] Fixed bad comment --- src/BlockArea.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index b4b519bc7..68976ab7a 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -1911,7 +1911,7 @@ bool cBlockArea::cChunkReader::Coords(int a_ChunkX, int a_ChunkZ) void cBlockArea::cChunkReader::ChunkBuffer(const cChunkBuffer & a_BlockBuffer) { - { // BlockTypes + { if (!(m_Area.m_BlockTypes == NULL)) { int SizeY = m_Area.m_Size.y; From 1d3ad6faa22a040bc6bb15727b9783ae2f547a02 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 27 Apr 2014 12:25:03 -0700 Subject: [PATCH 011/312] Added Testing capability --- CMakeLists.txt | 7 ++++++- lib/polarssl.cmake | 6 +++++- tests/CMakeLists.txt | 5 +++++ tests/ChunkBuffer/CMakeLists.txt | 10 ++++++++++ tests/ChunkBuffer/creatable.cpp | 4 ++++ 5 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/ChunkBuffer/CMakeLists.txt create mode 100644 tests/ChunkBuffer/creatable.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a860920c..45fc8c37a 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) @@ -69,3 +69,8 @@ set_exe_flags() add_subdirectory (src) +if(${SELF_TEST}) + enable_testing() + add_subdirectory (tests) +endif() + diff --git a/lib/polarssl.cmake b/lib/polarssl.cmake index d57cc9220..2a58e54c5 100644 --- a/lib/polarssl.cmake +++ b/lib/polarssl.cmake @@ -1,5 +1,9 @@ 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) + 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/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 000000000..c2f9ceb5a --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required (VERSION 2.6) + +enable_testing() + +add_subdirectory(ChunkBuffer) diff --git a/tests/ChunkBuffer/CMakeLists.txt b/tests/ChunkBuffer/CMakeLists.txt new file mode 100644 index 000000000..33722f785 --- /dev/null +++ b/tests/ChunkBuffer/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required (VERSION 2.6) + +enable_testing() + +add_library(ChunkBuffer ${CMAKE_SOURCE_DIR}/src/ChunkBuffer.cpp) + + +add_executable(creatable-exe creatable.cpp) +target_link_libraries(creatable-exe ChunkBuffer) +add_test(NAME creatable-test COMMAND creatable-exe) diff --git a/tests/ChunkBuffer/creatable.cpp b/tests/ChunkBuffer/creatable.cpp new file mode 100644 index 000000000..573f09de9 --- /dev/null +++ b/tests/ChunkBuffer/creatable.cpp @@ -0,0 +1,4 @@ +int main(int argc, char** argv) +{ +return 0; +} From 1929b46affd7e8ae98230faa726a896eef75cb16 Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 1 May 2014 11:52:08 -0700 Subject: [PATCH 012/312] Disable polarssl tests by default --- lib/polarssl.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/polarssl.cmake b/lib/polarssl.cmake index 2a58e54c5..4a2af9dfd 100644 --- a/lib/polarssl.cmake +++ b/lib/polarssl.cmake @@ -2,6 +2,7 @@ if(NOT TARGET polarssl) message("including polarssl") if (SELF_TEST) + set(ENABLE_TESTING 0) 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) From 47cc1a84e186f76f69ad432c081ae74ff6c80a6e Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 1 May 2014 11:57:07 -0700 Subject: [PATCH 013/312] Tests off by default take 2 --- lib/polarssl.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/polarssl.cmake b/lib/polarssl.cmake index 4a2af9dfd..172a63729 100644 --- a/lib/polarssl.cmake +++ b/lib/polarssl.cmake @@ -2,7 +2,7 @@ if(NOT TARGET polarssl) message("including polarssl") if (SELF_TEST) - set(ENABLE_TESTING 0) + set(ENABLE_TESTING OFF CACHE BOOL) 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) From 8d6919f3b63338ec01eff15a3968b004bd3be132 Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 1 May 2014 12:05:11 -0700 Subject: [PATCH 014/312] Fixed polarssl programs included --- lib/polarssl.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/polarssl.cmake b/lib/polarssl.cmake index 172a63729..91f0fa145 100644 --- a/lib/polarssl.cmake +++ b/lib/polarssl.cmake @@ -2,7 +2,8 @@ if(NOT TARGET polarssl) message("including polarssl") if (SELF_TEST) - set(ENABLE_TESTING OFF CACHE BOOL) + 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) From 616ddf5ca50450279198775a598796bb367cf8ce Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 3 May 2014 06:02:51 -0700 Subject: [PATCH 015/312] cCHunkBuffer that compiles with TestGlobals.h --- src/BiomeDef.h | 2 +- src/ChunkBuffer.h | 7 +++++++ src/StringUtils.h | 3 +++ src/Vector3.h | 2 ++ tests/CMakeLists.txt | 2 ++ tests/ChunkBuffer/CMakeLists.txt | 6 ++++++ tests/ChunkBuffer/creatable.cpp | 7 ++++++- 7 files changed, 27 insertions(+), 2 deletions(-) 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/ChunkBuffer.h b/src/ChunkBuffer.h index c23f8971d..410532232 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -1,6 +1,13 @@ #pragma once + +#include + + +#include "ChunkDef.h" + + #define CHUNK_SECTION_HEIGHT 16 #define CHUNK_SECTION_NUM (256 / CHUNK_SECTION_HEIGHT) diff --git a/src/StringUtils.h b/src/StringUtils.h index b69e47d3c..347fbe909 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -11,6 +11,9 @@ +#include + + typedef std::string AString; diff --git a/src/Vector3.h b/src/Vector3.h index 2c79f9ff1..53fdcf6df 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -5,6 +5,8 @@ #define _USE_MATH_DEFINES // Enable non-standard math defines (MSVC) #include +#include +#include diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c2f9ceb5a..1e3a01dc8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,4 +2,6 @@ cmake_minimum_required (VERSION 2.6) enable_testing() +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + add_subdirectory(ChunkBuffer) diff --git a/tests/ChunkBuffer/CMakeLists.txt b/tests/ChunkBuffer/CMakeLists.txt index 33722f785..08d01d1a0 100644 --- a/tests/ChunkBuffer/CMakeLists.txt +++ b/tests/ChunkBuffer/CMakeLists.txt @@ -2,9 +2,15 @@ cmake_minimum_required (VERSION 2.6) enable_testing() +include_directories(${CMAKE_SOURCE_DIR}/src/) + add_library(ChunkBuffer ${CMAKE_SOURCE_DIR}/src/ChunkBuffer.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) diff --git a/tests/ChunkBuffer/creatable.cpp b/tests/ChunkBuffer/creatable.cpp index 573f09de9..49204c879 100644 --- a/tests/ChunkBuffer/creatable.cpp +++ b/tests/ChunkBuffer/creatable.cpp @@ -1,4 +1,9 @@ + +#include "TestGlobals.h" +#include "ChunkBuffer.h" + int main(int argc, char** argv) { -return 0; + cChunkBuffer buffer; + return 0; } From 77395b37390ecf23218659925c61e0a9b44d8476 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 05:03:36 -0700 Subject: [PATCH 016/312] Maybe coverage working? --- .travis.yml | 14 ++- CIbuild.sh | 6 + CMakeLists.txt | 4 + SetFlags.cmake | 79 +++++++------ lib/cmake-coverage/CodeCoverage.cmake | 160 ++++++++++++++++++++++++++ lib/cmake-coverage/LICENSE | 23 ++++ tests/ChunkBuffer/Coordinates.cpp | 15 +++ tests/TestGlobals.h | 136 ++++++++++++++++++++++ uploadCoverage.sh | 5 + 9 files changed, 409 insertions(+), 33 deletions(-) create mode 100644 CIbuild.sh create mode 100644 lib/cmake-coverage/CodeCoverage.cmake create mode 100644 lib/cmake-coverage/LICENSE create mode 100644 tests/ChunkBuffer/Coordinates.cpp create mode 100644 tests/TestGlobals.h create mode 100644 uploadCoverage.sh diff --git a/.travis.yml b/.travis.yml index 0ab25ae3b..3bf2acc43 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_debug + # Notification Settings notifications: email: diff --git a/CIbuild.sh b/CIbuild.sh new file mode 100644 index 000000000..0c00a351f --- /dev/null +++ b/CIbuild.sh @@ -0,0 +1,6 @@ + #!/usr/bin/env bash + +cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1; +make -j 2; +cd MCServer/; +echo stop | gcov $MCSERVER_PATH; diff --git a/CMakeLists.txt b/CMakeLists.txt index 45fc8c37a..56dea1a34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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/) diff --git a/SetFlags.cmake b/SetFlags.cmake index 4eed529bd..c4713e2d2 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,7 @@ 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) + set(CMAKE_CONFIGURATION_TYPES "Debug;Release;DebugProfile;ReleaseProfile;Coverage" CACHE STRING "" FORCE) endmacro() macro(set_exe_flags) @@ -180,10 +193,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/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/tests/ChunkBuffer/Coordinates.cpp b/tests/ChunkBuffer/Coordinates.cpp new file mode 100644 index 000000000..d61eda7ad --- /dev/null +++ b/tests/ChunkBuffer/Coordinates.cpp @@ -0,0 +1,15 @@ + +#include "TestGlobals.h" +#include "ChunkBuffer.h" + + + +int main(int argc, char** argv) +{ + cChunkBuffer buffer; + buffer.SetBlock(0,0,0, 0xAB); + assert(buffer.GetBlock(0,0,0) == 0xAB); + buffer.SetMeta(0,16,0, 0xC); + assert(buffer.GetMeta(0,16,0) == 0xC); + return 0; +} diff --git a/tests/TestGlobals.h b/tests/TestGlobals.h new file mode 100644 index 000000000..cb8fc9376 --- /dev/null +++ b/tests/TestGlobals.h @@ -0,0 +1,136 @@ + + +#include +#include +#include + + +// Compiler-dependent stuff: +#if defined(_MSC_VER) + // MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether + #pragma warning(disable:4481) + + // Disable some warnings that we don't care about: + #pragma warning(disable:4100) // Unreferenced formal parameter + + // Useful warnings from warning level 4: + #pragma warning(3 : 4127) // Conditional expression is constant + #pragma warning(3 : 4189) // Local variable is initialized but not referenced + #pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed/unsigned mismatch + #pragma warning(3 : 4310) // Cast truncates constant value + #pragma warning(3 : 4389) // Signed/unsigned mismatch + #pragma warning(3 : 4505) // Unreferenced local function has been removed + #pragma warning(3 : 4701) // Potentially unitialized local variable used + #pragma warning(3 : 4702) // Unreachable code + #pragma warning(3 : 4706) // Assignment within conditional expression + + // Disabling this warning, because we know what we're doing when we're doing this: + #pragma warning(disable: 4355) // 'this' used in initializer list + + // Disabled because it's useless: + #pragma warning(disable: 4512) // 'class': assignment operator could not be generated - reported for each class that has a reference-type member + + // 2014_01_06 xoft: Disabled this warning because MSVC is stupid and reports it in obviously wrong places + // #pragma warning(3 : 4244) // Conversion from 'type1' to 'type2', possible loss of data + + #define OBSOLETE __declspec(deprecated) + + // No alignment needed in MSVC + #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)? + #define abstract + + // override is part of c++11 + #if __cplusplus < 201103L + #define override + #endif + + #define OBSOLETE __attribute__((deprecated)) + + #define ALIGN_8 __attribute__((aligned(8))) + #define ALIGN_16 __attribute__((aligned(16))) + + // 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" + + /* + // Copy and uncomment this into another #elif section based on your compiler identification + + // Explicitly mark classes as abstract (no instances can be created) + #define abstract + + // Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class) + #define override + + // Mark functions as obsolete, so that their usage results in a compile-time warning + #define OBSOLETE + + // Mark types / variables for alignment. Do the platforms need it? + #define ALIGN_8 + #define ALIGN_16 + */ + +#endif + + + +// Integral types with predefined sizes: +typedef long long Int64; +typedef int Int32; +typedef short Int16; + +typedef unsigned long long UInt64; +typedef unsigned int UInt32; +typedef unsigned short UInt16; + +typedef unsigned char Byte; + + + +#define ASSERT(x) assert(x) + + +#ifndef TOLUA_TEMPLATE_BIND +#define TOLUA_TEMPLATE_BIND(x) +#endif + +// A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc +#define UNUSED(X) (void)(X) + +// Logging functions +void LOGERROR(const char* a_Format, ...) FORMATSTRING(1,2); + +void LOGERROR(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + vprintf(a_Format, argList); + va_end(argList); +} + + diff --git a/uploadCoverage.sh b/uploadCoverage.sh new file mode 100644 index 000000000..0897479ae --- /dev/null +++ b/uploadCoverage.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +if [TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"] then + coveralls --exclude lib --exclude tests +fi From 604ed439a8a67f16f8af75a31630b2c5b3ece7f1 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 13:09:47 +0100 Subject: [PATCH 017/312] Fix bash ifs --- .travis.yml | 2 +- MCServer/Plugins/Core | 2 +- uploadCoverage.sh | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3bf2acc43..1adc0c8ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ compiler: - clang before_install: - - if [TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"] then sudo pip install cpp_coveralls fi + - if [TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"]; then sudo pip install cpp_coveralls; fi # Build MCServer script: CIbuild.sh diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 5c8557d4f..013a32a7f 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 5c8557d4fdfa580c100510cde07a1a778ea2e244 +Subproject commit 013a32a7fb3c8a6cfe0aef892d4c7394d4e1be59 diff --git a/uploadCoverage.sh b/uploadCoverage.sh index 0897479ae..3a566d990 100644 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash -if [TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"] then - coveralls --exclude lib --exclude tests +if [TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"] + then + coveralls --exclude lib --exclude tests fi From b66b1e5b1072fa141f04a7ae7eeaab0099ff09eb Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 13:12:01 +0100 Subject: [PATCH 018/312] Fixed paths --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1adc0c8ef..2d0c0a337 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,10 @@ before_install: - if [TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"]; then sudo pip install cpp_coveralls; fi # Build MCServer -script: CIbuild.sh +script: ./CIbuild.sh after_success: - - uploadCoverage.sh + - ./uploadCoverage.sh env: - TRAVIS_MCSERVER_BUILD_TYPE=RELEASE MCSERVER_PATH=./MCServer From 5be9bac448e05bd5f352ec6df2604ee7631d5e33 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 13:12:57 +0100 Subject: [PATCH 019/312] Fixed missing Dollar signs --- .travis.yml | 2 +- uploadCoverage.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d0c0a337..0da5487f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ compiler: - clang before_install: - - if [TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"]; then sudo pip install cpp_coveralls; fi + - if [$TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"]; then sudo pip install cpp_coveralls; fi # Build MCServer script: ./CIbuild.sh diff --git a/uploadCoverage.sh b/uploadCoverage.sh index 3a566d990..6ea5e481a 100644 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -if [TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"] +if [$TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"] then coveralls --exclude lib --exclude tests fi From cebbb8abd01f26a9f9e998882506890ed7560bdc Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 13:14:32 +0100 Subject: [PATCH 020/312] Make scripts executable --- CIbuild.sh | 0 uploadCoverage.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 CIbuild.sh mode change 100644 => 100755 uploadCoverage.sh diff --git a/CIbuild.sh b/CIbuild.sh old mode 100644 new mode 100755 diff --git a/uploadCoverage.sh b/uploadCoverage.sh old mode 100644 new mode 100755 From 6e6d7c1159608c7e068f60aafca945473829bf68 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 13:17:09 +0100 Subject: [PATCH 021/312] Fix spaces in bash --- .travis.yml | 2 +- uploadCoverage.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0da5487f7..b7dc01d9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ compiler: - clang before_install: - - if [$TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"]; then sudo pip install cpp_coveralls; fi + - if [ $TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE" ]; then sudo pip install cpp_coveralls; fi # Build MCServer script: ./CIbuild.sh diff --git a/uploadCoverage.sh b/uploadCoverage.sh index 6ea5e481a..177401de3 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -if [$TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE"] +if [ $TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE" ] then coveralls --exclude lib --exclude tests fi From 189c7529e974065918476a5ac60d0318606c7c5f Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 13:18:40 +0100 Subject: [PATCH 022/312] Add qutes to scripts --- .travis.yml | 2 +- uploadCoverage.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b7dc01d9c..73d7eb557 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ compiler: - clang before_install: - - if [ $TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE" ]; then sudo pip install cpp_coveralls; fi + - if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ]; then sudo pip install cpp_coveralls; fi # Build MCServer script: ./CIbuild.sh diff --git a/uploadCoverage.sh b/uploadCoverage.sh index 177401de3..193e670dc 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -if [ $TRAVIS_MCSERVER_BUILD_TYPE == "COVERAGE" ] +if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then coveralls --exclude lib --exclude tests fi From 740aed3aefb48007233e0c31e28b349c74178180 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 13:46:05 +0100 Subject: [PATCH 023/312] Relocate gcda files so gcov can find them --- CIbuild.sh | 1 + uploadCoverage.sh | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CIbuild.sh b/CIbuild.sh index 0c00a351f..4d8b313a5 100755 --- a/CIbuild.sh +++ b/CIbuild.sh @@ -2,5 +2,6 @@ cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1; make -j 2; +make -j 2 test; cd MCServer/; echo stop | gcov $MCSERVER_PATH; diff --git a/uploadCoverage.sh b/uploadCoverage.sh index 193e670dc..6bc75f779 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -2,5 +2,8 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then + find tests -type f -name '*.gcda' -exec 'cp {} $(dirname {})/../$(basename {})' coveralls --exclude lib --exclude tests fi + + From 79570552b94c9777244a91efe3f528ff437951d7 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 13:57:46 +0100 Subject: [PATCH 024/312] Relocate gcda files so gcov can find them take 2 --- uploadCoverage.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index 6bc75f779..f3f9eae1a 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -2,8 +2,8 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then - find tests -type f -name '*.gcda' -exec 'cp {} $(dirname {})/../$(basename {})' - coveralls --exclude lib --exclude tests + find tests -type f -name '*.gcda' -exec cp {} $(dirname {})/../$(basename {}) + coveralls --exclude lib --exclude tests > fi From 9e17adc8454c444628c89d4e4782a4e8337295da Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 13:59:34 +0100 Subject: [PATCH 025/312] quieted gcov --- uploadCoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index f3f9eae1a..ad3ea070e 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -3,7 +3,7 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then find tests -type f -name '*.gcda' -exec cp {} $(dirname {})/../$(basename {}) - coveralls --exclude lib --exclude tests > + coveralls --exclude lib --exclude tests --gcov-options -q fi From 5b23bc53cc200b5fe9592c3c5f6fda1622e99b54 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 14:05:39 +0100 Subject: [PATCH 026/312] rewrote exclustions --- uploadCoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index ad3ea070e..b76b9d8e6 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -3,7 +3,7 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then find tests -type f -name '*.gcda' -exec cp {} $(dirname {})/../$(basename {}) - coveralls --exclude lib --exclude tests --gcov-options -q + coveralls --exclude lib --exclude Android --gcov-options -q fi From 149793da05d67f710e0c5994f464dc7d4b2bb0e2 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 14:11:35 +0100 Subject: [PATCH 027/312] Relocate gcda files so gcov can find them 3 --- uploadCoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index b76b9d8e6..3c50dc2f5 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -2,7 +2,7 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then - find tests -type f -name '*.gcda' -exec cp {} $(dirname {})/../$(basename {}) + find tests -type f -name '*.gcda' -exec sh -c 'cp {} $(dirname {})/../$(basename {})' \; coveralls --exclude lib --exclude Android --gcov-options -q fi From 3b8f28aa49e53af8c5832a6975fea85ede583a35 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 14:13:25 +0100 Subject: [PATCH 028/312] quieted gcov 2 --- uploadCoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index 3c50dc2f5..f9b396a8c 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -3,7 +3,7 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then find tests -type f -name '*.gcda' -exec sh -c 'cp {} $(dirname {})/../$(basename {})' \; - coveralls --exclude lib --exclude Android --gcov-options -q + coveralls --exclude lib --exclude Android --gcov-options q fi From 90f91ae97748ebc6044c50fb7826eea098ae7a2f Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 14:34:08 +0100 Subject: [PATCH 029/312] quieted gcov 3 --- uploadCoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index f9b396a8c..7eb1d9983 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -3,7 +3,7 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then find tests -type f -name '*.gcda' -exec sh -c 'cp {} $(dirname {})/../$(basename {})' \; - coveralls --exclude lib --exclude Android --gcov-options q + coveralls --exclude lib --exclude Android --gcov-options ' -q' fi From 83a7b2333f8cf226ace35c09fa68a6a0f8009434 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 14:44:20 +0100 Subject: [PATCH 030/312] quieted gcov 4 --- uploadCoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index 7eb1d9983..fc17ddc2c 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -3,7 +3,7 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then find tests -type f -name '*.gcda' -exec sh -c 'cp {} $(dirname {})/../$(basename {})' \; - coveralls --exclude lib --exclude Android --gcov-options ' -q' + coveralls --exclude lib --exclude Android >/dev/null fi From cb6200345cdfcf34ab4cd6b50cc268152324f9dd Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 15:19:06 +0100 Subject: [PATCH 031/312] Fixed bug in setting metas --- src/Chunk.cpp | 18 ------------------ src/Chunk.h | 8 +++++++- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 0303e1502..a986ac076 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1568,24 +1568,6 @@ 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) { diff --git a/src/Chunk.h b/src/Chunk.h index d2328971f..26f1e9d10 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -328,7 +328,13 @@ public: } inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { - m_ChunkBuffer.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta); + if (!GetMeta(a_RelX, a_RelY, a_RelZ) == a_Meta) + { + MarkDirty(); + m_ChunkBuffer.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta); + + 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 m_ChunkBuffer.GetBlockLight(a_RelX, a_RelY, a_RelZ); } From 0940747f3b5dea69bf0d32cb4657b69f3a03d0dd Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 15:30:48 +0100 Subject: [PATCH 032/312] Added some more tests --- tests/ChunkBuffer/Coordinates.cpp | 95 ++++++++++++++++++++++++++++++- tests/TestGlobals.h | 11 ++-- 2 files changed, 100 insertions(+), 6 deletions(-) diff --git a/tests/ChunkBuffer/Coordinates.cpp b/tests/ChunkBuffer/Coordinates.cpp index d61eda7ad..a6a8aa18f 100644 --- a/tests/ChunkBuffer/Coordinates.cpp +++ b/tests/ChunkBuffer/Coordinates.cpp @@ -7,9 +7,100 @@ int main(int argc, char** argv) { cChunkBuffer buffer; + + // Empty chunks buffer.SetBlock(0,0,0, 0xAB); - assert(buffer.GetBlock(0,0,0) == 0xAB); + testassert(buffer.GetBlock(0,0,0) == 0xAB); buffer.SetMeta(0,16,0, 0xC); - assert(buffer.GetMeta(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); + ); + return 0; } diff --git a/tests/TestGlobals.h b/tests/TestGlobals.h index cb8fc9376..bb25bd20a 100644 --- a/tests/TestGlobals.h +++ b/tests/TestGlobals.h @@ -1,8 +1,8 @@ -#include #include #include +#include // Compiler-dependent stuff: @@ -110,10 +110,13 @@ typedef unsigned short UInt16; typedef unsigned char Byte; +class cAssertFailure +{ +}; - -#define ASSERT(x) assert(x) - +#define ASSERT(x) do { if (!(x)) { throw cAssertFailure();} } while (0) +#define testassert(x) do { if(!(x)) { exit(1); } } while (0) +#define CheckAsserts(x) do { try {x} catch (cAssertFailure) { break; } exit(1); } while (0) #ifndef TOLUA_TEMPLATE_BIND #define TOLUA_TEMPLATE_BIND(x) From 29d5f8eb0a728d9224ace739c1787f25aac82e0a Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 16:08:08 +0100 Subject: [PATCH 033/312] Added new test --- tests/ChunkBuffer/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/ChunkBuffer/CMakeLists.txt b/tests/ChunkBuffer/CMakeLists.txt index 08d01d1a0..73dc79e25 100644 --- a/tests/ChunkBuffer/CMakeLists.txt +++ b/tests/ChunkBuffer/CMakeLists.txt @@ -14,3 +14,7 @@ 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) From ba25f6b5244f37a3b79a496e8bc65447fc9bd2e4 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 16:15:45 +0100 Subject: [PATCH 034/312] Add arries copies tests --- tests/ChunkBuffer/Copies.cpp | 53 ++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 tests/ChunkBuffer/Copies.cpp diff --git a/tests/ChunkBuffer/Copies.cpp b/tests/ChunkBuffer/Copies.cpp new file mode 100644 index 000000000..2f5d48e6a --- /dev/null +++ b/tests/ChunkBuffer/Copies.cpp @@ -0,0 +1,53 @@ + +#include "TestGlobals.h" +#include "ChunkBuffer.h" + + + +int main(int argc, char** argv) +{ + cChunkBuffer buffer; + + buffer.SetBlock(3,1,4,0xDE); + buffer.SetMeta(3,1,4,0xA); + + cChunkBuffer copy = buffer.Copy(); + testassert(copy.GetBlock(3,1,4) == 0xDE); + testassert(copy.GetMeta(3,1,4) == 0xA); + + BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[256 * 256 * 256]; + for (int i = 0; i < 256* 256 * 256; i += 4) + { + SrcBlockBuffer[i+0] = 0xDE; + SrcBlockBuffer[i+1] = 0xAD; + SrcBlockBuffer[i+2] = 0xBE; + SrcBlockBuffer[i+3] = 0xEF; + } + + buffer.SetBlocks(SrcBlockBuffer); + BLOCKTYPE * DstBlockBuffer = new BLOCKTYPE[256 * 256 * 256]; + buffer.CopyBlocks(DstBlockBuffer); + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (256 * 256 * 256) -1) == 0); + delete SrcBlockBuffer; + delete DstBlockBuffer; + SrcBlockBuffer = NULL; + DstBlockBuffer = NULL; + + NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[256 * 256 * 256/2]; + for (int i = 0; i < 256* 256 * 256 / 2; i += 4) + { + SrcNibbleBuffer[i+0] = 0xEF; + SrcNibbleBuffer[i+1] = 0xDE; + SrcNibbleBuffer[i+2] = 0xAD; + SrcNibbleBuffer[i+3] = 0xBE; + } + + buffer.SetMeta(SrcNibbleBuffer); + NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[256 * 256 * 256/ 2]; + buffer.CopyMeta(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (256 * 256 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; +} From 0adb5c94b8230b7a65fc06f90c253576755cedcd Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 17:46:49 +0100 Subject: [PATCH 035/312] Fixed stupid buffer overflow in array setblocks --- src/ChunkBuffer.cpp | 6 +++--- src/ChunkBuffer.h | 4 ++-- tests/ChunkBuffer/Copies.cpp | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ChunkBuffer.cpp b/src/ChunkBuffer.cpp index a41b8f61a..baeeff890 100644 --- a/src/ChunkBuffer.cpp +++ b/src/ChunkBuffer.cpp @@ -35,7 +35,7 @@ void cChunkBuffer::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length memcpy( &a_dest[i * segment_length], &m_Sections[i]->m_BlockTypes, - sizeof(BLOCKTYPE) * length + sizeof(BLOCKTYPE) * tocopy ); } else @@ -43,7 +43,7 @@ void cChunkBuffer::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length memset( &a_dest[i * segment_length], 0, - sizeof(BLOCKTYPE) * length + sizeof(BLOCKTYPE) * tocopy ); } } @@ -141,7 +141,7 @@ void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) { for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; if (m_Sections[i]) { memcpy(&m_Sections[i]->m_BlockTypes, &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length); diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h index 410532232..b1bd024d5 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -124,7 +124,7 @@ public: m_Sections[Section] = Allocate(); if(!m_Sections[Section]) { - ASSERT("Failed to allocate a new section in Chunkbuffer"); + ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return; } } @@ -169,7 +169,7 @@ public: m_Sections[Section] = Allocate(); if(!m_Sections[Section]) { - ASSERT("Failed to allocate a new section in Chunkbuffer"); + ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return; } } diff --git a/tests/ChunkBuffer/Copies.cpp b/tests/ChunkBuffer/Copies.cpp index 2f5d48e6a..6bdf80268 100644 --- a/tests/ChunkBuffer/Copies.cpp +++ b/tests/ChunkBuffer/Copies.cpp @@ -15,8 +15,8 @@ int main(int argc, char** argv) testassert(copy.GetBlock(3,1,4) == 0xDE); testassert(copy.GetMeta(3,1,4) == 0xA); - BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[256 * 256 * 256]; - for (int i = 0; i < 256* 256 * 256; i += 4) + BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + for (int i = 0; i < 16 * 16 * 256; i += 4) { SrcBlockBuffer[i+0] = 0xDE; SrcBlockBuffer[i+1] = 0xAD; @@ -25,16 +25,16 @@ int main(int argc, char** argv) } buffer.SetBlocks(SrcBlockBuffer); - BLOCKTYPE * DstBlockBuffer = new BLOCKTYPE[256 * 256 * 256]; + BLOCKTYPE * DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; buffer.CopyBlocks(DstBlockBuffer); - testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (256 * 256 * 256) -1) == 0); + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); delete SrcBlockBuffer; delete DstBlockBuffer; SrcBlockBuffer = NULL; DstBlockBuffer = NULL; - NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[256 * 256 * 256/2]; - for (int i = 0; i < 256* 256 * 256 / 2; i += 4) + NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) { SrcNibbleBuffer[i+0] = 0xEF; SrcNibbleBuffer[i+1] = 0xDE; @@ -43,9 +43,9 @@ int main(int argc, char** argv) } buffer.SetMeta(SrcNibbleBuffer); - NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[256 * 256 * 256/ 2]; + NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; buffer.CopyMeta(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (256 * 256 * 256 /2) -1) == 0); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); delete SrcNibbleBuffer; delete DstNibbleBuffer; SrcNibbleBuffer = NULL; From 6124b5208cd91a510ade2ecbe1056ee2df36046f Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 17:47:45 +0100 Subject: [PATCH 036/312] quite gcov take 4 --- uploadCoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index fc17ddc2c..dc3ca5278 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -3,7 +3,7 @@ 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 + coveralls --exclude lib --exclude Android --gcov-options=-q fi From 4e6499c1c2d0473e0454c88128962154d0f8fc4f Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 17:51:20 +0100 Subject: [PATCH 037/312] Don't run start test under gcov --- CIbuild.sh | 2 +- uploadCoverage.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CIbuild.sh b/CIbuild.sh index 4d8b313a5..0e17f6e64 100755 --- a/CIbuild.sh +++ b/CIbuild.sh @@ -4,4 +4,4 @@ cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1; make -j 2; make -j 2 test; cd MCServer/; -echo stop | gcov $MCSERVER_PATH; +echo stop | $MCSERVER_PATH; diff --git a/uploadCoverage.sh b/uploadCoverage.sh index dc3ca5278..fc17ddc2c 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -3,7 +3,7 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then find tests -type f -name '*.gcda' -exec sh -c 'cp {} $(dirname {})/../$(basename {})' \; - coveralls --exclude lib --exclude Android --gcov-options=-q + coveralls --exclude lib --exclude Android >/dev/null fi From 7ebb0afd4ec1949f169589ac98438a1322454b1c Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 17:52:46 +0100 Subject: [PATCH 038/312] Fail build on error --- CIbuild.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CIbuild.sh b/CIbuild.sh index 0e17f6e64..20785a488 100755 --- a/CIbuild.sh +++ b/CIbuild.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash - + +set -e + cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1; make -j 2; make -j 2 test; From 7ca33bd832575ea94f8409087c804feb86280c15 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 17:56:59 +0100 Subject: [PATCH 039/312] Fixed stupid error --- src/Chunk.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Chunk.h b/src/Chunk.h index 26f1e9d10..038be42de 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -328,7 +328,7 @@ public: } inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { - if (!GetMeta(a_RelX, a_RelY, a_RelZ) == a_Meta) + if (!(GetMeta(a_RelX, a_RelY, a_RelZ) == a_Meta)) { MarkDirty(); m_ChunkBuffer.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta); From 009f749962cca2e8914d60b29d971923af9c0226 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 10 May 2014 18:07:50 +0100 Subject: [PATCH 040/312] Coverage builds are called MCServer not MCServer_debug --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 73d7eb557..5260cfd17 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ env: matrix: include: - compiler: gcc - env: TRAVIS_MCSERVER_BUILD_TYPE=COVERAGE MCSERVER_PATH=./MCServer_debug + env: TRAVIS_MCSERVER_BUILD_TYPE=COVERAGE MCSERVER_PATH=./MCServer # Notification Settings notifications: From 9278bb732d115251776b12ebb45d0192c7fdd916 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 11 May 2014 15:52:02 +0100 Subject: [PATCH 041/312] Fixed a bug in writting zeros to a non-allocated section --- src/ChunkBuffer.cpp | 11 ++ src/ChunkBuffer.h | 12 ++ tests/ChunkBuffer/Coordinates.cpp | 204 ++++++++++++++++-------------- 3 files changed, 134 insertions(+), 93 deletions(-) diff --git a/src/ChunkBuffer.cpp b/src/ChunkBuffer.cpp index baeeff890..96077b966 100644 --- a/src/ChunkBuffer.cpp +++ b/src/ChunkBuffer.cpp @@ -295,3 +295,14 @@ void cChunkBuffer::Free(cChunkBuffer::sChunkSection * ptr) const +void cChunkBuffer::ZeroSection(cChunkBuffer::sChunkSection * ptr) const +{ + memset(ptr->m_BlockTypes,0x00,sizeof(ptr->m_BlockTypes)); + memset(ptr->m_BlockMeta,0x00,sizeof(ptr->m_BlockMeta)); + memset(ptr->m_BlockLight,0x00,sizeof(ptr->m_BlockLight)); + memset(ptr->m_BlockSkyLight,0x00,sizeof(ptr->m_BlockSkyLight)); +} + + + + diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h index b1bd024d5..e16575bb2 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -121,12 +121,17 @@ public: int Section = a_RelY / CHUNK_SECTION_HEIGHT; if(!m_Sections[Section]) { + if(a_Block == 0x00) + { + return; + } m_Sections[Section] = Allocate(); if(!m_Sections[Section]) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return; } + ZeroSection(m_Sections[Section]); } int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); m_Sections[Section]->m_BlockTypes[Index] = a_Block; @@ -166,12 +171,17 @@ public: int Section = a_RelY / CHUNK_SECTION_HEIGHT; if(!m_Sections[Section]) { + if((a_Nibble & 0xf) == 0x00) + { + return; + } m_Sections[Section] = Allocate(); if(!m_Sections[Section]) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return; } + ZeroSection(m_Sections[Section]); } int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); m_Sections[Section]->m_BlockMeta[Index / 2] = static_cast( @@ -247,6 +257,8 @@ private: sChunkSection * Allocate() const; void Free(sChunkSection * ptr) const; + + void ZeroSection(sChunkSection * ptr) const; }; diff --git a/tests/ChunkBuffer/Coordinates.cpp b/tests/ChunkBuffer/Coordinates.cpp index a6a8aa18f..b9861df23 100644 --- a/tests/ChunkBuffer/Coordinates.cpp +++ b/tests/ChunkBuffer/Coordinates.cpp @@ -6,101 +6,119 @@ int main(int argc, char** argv) { - cChunkBuffer buffer; + { + cChunkBuffer buffer; + + // 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); + ); + } - // 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); + { + cChunkBuffer buffer; + + // 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); + } - // 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); - ); return 0; } From 79ab80718ef18f174c73ecb804cb8604e0717fa5 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 11 May 2014 15:57:56 +0100 Subject: [PATCH 042/312] Cerated array copy tests for block and skylight --- tests/ChunkBuffer/Copies.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/ChunkBuffer/Copies.cpp b/tests/ChunkBuffer/Copies.cpp index 6bdf80268..a6c83f75d 100644 --- a/tests/ChunkBuffer/Copies.cpp +++ b/tests/ChunkBuffer/Copies.cpp @@ -50,4 +50,40 @@ int main(int argc, char** argv) delete DstNibbleBuffer; SrcNibbleBuffer = NULL; DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[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.SetLight(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) + { + SrcNibbleBuffer[i+0] = 0xAD; + SrcNibbleBuffer[i+1] = 0xBE; + SrcNibbleBuffer[i+2] = 0xEF; + SrcNibbleBuffer[i+3] = 0xDE; + } + + buffer.SetSkyLight(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopySkyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; } From 9568c223ff5b507ab436931ddf716e5978cbc35e Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 11 May 2014 18:24:21 +0100 Subject: [PATCH 043/312] SkyLight defaults to 0xFF --- src/ChunkBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChunkBuffer.cpp b/src/ChunkBuffer.cpp index 96077b966..73ccd9c02 100644 --- a/src/ChunkBuffer.cpp +++ b/src/ChunkBuffer.cpp @@ -300,7 +300,7 @@ void cChunkBuffer::ZeroSection(cChunkBuffer::sChunkSection * ptr) const memset(ptr->m_BlockTypes,0x00,sizeof(ptr->m_BlockTypes)); memset(ptr->m_BlockMeta,0x00,sizeof(ptr->m_BlockMeta)); memset(ptr->m_BlockLight,0x00,sizeof(ptr->m_BlockLight)); - memset(ptr->m_BlockSkyLight,0x00,sizeof(ptr->m_BlockSkyLight)); + memset(ptr->m_BlockSkyLight,0xFF,sizeof(ptr->m_BlockSkyLight)); } From a6940445f66948f2dbaa5eaffaa6a89cc15942cb Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 11 May 2014 18:29:47 +0100 Subject: [PATCH 044/312] test 0 values --- tests/ChunkBuffer/Copies.cpp | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/ChunkBuffer/Copies.cpp b/tests/ChunkBuffer/Copies.cpp index a6c83f75d..07879d129 100644 --- a/tests/ChunkBuffer/Copies.cpp +++ b/tests/ChunkBuffer/Copies.cpp @@ -86,4 +86,49 @@ int main(int argc, char** argv) delete DstNibbleBuffer; SrcNibbleBuffer = NULL; DstNibbleBuffer = NULL; + + SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); + buffer.SetBlocks(SrcBlockBuffer); + DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + buffer.CopyBlocks(DstBlockBuffer); + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); + delete SrcBlockBuffer; + delete DstBlockBuffer; + SrcBlockBuffer = NULL; + DstBlockBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + buffer.SetMeta(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyMeta(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + buffer.SetLight(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); + buffer.SetSkyLight(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopySkyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; } From 5d39ecc64b3c690b2da05936c73c9442511b9509 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 11 May 2014 18:42:38 +0100 Subject: [PATCH 045/312] Fixed bug that caused Array Setters to always create segments --- src/ChunkBuffer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ChunkBuffer.cpp b/src/ChunkBuffer.cpp index 73ccd9c02..141601113 100644 --- a/src/ChunkBuffer.cpp +++ b/src/ChunkBuffer.cpp @@ -151,7 +151,7 @@ void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); - if (j != segment_length) + if (j != (segment_length - 1)) { m_Sections[i] = Allocate(); memcpy( @@ -186,7 +186,7 @@ void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); - if (j != segment_length) + if (j != (segment_length - 1)) { m_Sections[i] = Allocate(); memcpy( @@ -222,7 +222,7 @@ void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); - if (j != segment_length) + if (j != (segment_length - 1)) { m_Sections[i] = Allocate(); memcpy( @@ -258,7 +258,7 @@ void cChunkBuffer::SetSkyLight (const NIBBLETYPE * a_src) size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0xFF; j++); - if (j != segment_length) + if (j != (segment_length -1)) { m_Sections[i] = Allocate(); memcpy( From c46f240d818e5e6aa7c1ffae95bd03f979aae8ba Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 11 May 2014 19:24:09 +0100 Subject: [PATCH 046/312] Added several more testsfor arrays and coordinates --- src/ChunkBuffer.cpp | 20 ++++++++++++++++---- tests/ChunkBuffer/CMakeLists.txt | 5 +++++ tests/ChunkBuffer/Copies.cpp | 1 - 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/ChunkBuffer.cpp b/src/ChunkBuffer.cpp index 141601113..99bcdebef 100644 --- a/src/ChunkBuffer.cpp +++ b/src/ChunkBuffer.cpp @@ -151,7 +151,7 @@ void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); - if (j != (segment_length - 1)) + if (j != segment_length) { m_Sections[i] = Allocate(); memcpy( @@ -159,6 +159,9 @@ void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); + memset(m_Sections[i]->m_BlockMeta,0x00,sizeof(m_Sections[i]->m_BlockMeta)); + 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)); } else { @@ -186,7 +189,7 @@ void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); - if (j != (segment_length - 1)) + if (j != segment_length) { m_Sections[i] = Allocate(); memcpy( @@ -194,6 +197,9 @@ void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); + 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)); } else { @@ -222,7 +228,7 @@ void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); - if (j != (segment_length - 1)) + if (j != segment_length) { m_Sections[i] = Allocate(); memcpy( @@ -230,6 +236,9 @@ void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); + memset(m_Sections[i]->m_BlockTypes,0x00,sizeof(m_Sections[i]->m_BlockTypes)); + memset(m_Sections[i]->m_BlockMeta,0x00,sizeof(m_Sections[i]->m_BlockMeta)); + memset(m_Sections[i]->m_BlockSkyLight,0xFF,sizeof(m_Sections[i]->m_BlockSkyLight)); } else { @@ -258,7 +267,7 @@ void cChunkBuffer::SetSkyLight (const NIBBLETYPE * a_src) size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0xFF; j++); - if (j != (segment_length -1)) + if (j != segment_length) { m_Sections[i] = Allocate(); memcpy( @@ -266,6 +275,9 @@ void cChunkBuffer::SetSkyLight (const NIBBLETYPE * a_src) &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); + memset(m_Sections[i]->m_BlockTypes,0x00,sizeof(m_Sections[i]->m_BlockTypes)); + memset(m_Sections[i]->m_BlockMeta,0x00,sizeof(m_Sections[i]->m_BlockMeta)); + memset(m_Sections[i]->m_BlockLight,0x00,sizeof(m_Sections[i]->m_BlockLight)); } else { diff --git a/tests/ChunkBuffer/CMakeLists.txt b/tests/ChunkBuffer/CMakeLists.txt index 73dc79e25..b216b1d39 100644 --- a/tests/ChunkBuffer/CMakeLists.txt +++ b/tests/ChunkBuffer/CMakeLists.txt @@ -18,3 +18,8 @@ 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) + diff --git a/tests/ChunkBuffer/Copies.cpp b/tests/ChunkBuffer/Copies.cpp index 07879d129..eb149f25f 100644 --- a/tests/ChunkBuffer/Copies.cpp +++ b/tests/ChunkBuffer/Copies.cpp @@ -99,7 +99,6 @@ int main(int argc, char** argv) DstBlockBuffer = NULL; SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); buffer.SetMeta(SrcNibbleBuffer); DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; From 97dc7d8f660c39a037526fa3d164066de218a6a2 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 11 May 2014 19:40:32 +0100 Subject: [PATCH 047/312] Added some more tests --- tests/ChunkBuffer/ArraytoCoord.cpp | 81 ++++++++ tests/ChunkBuffer/Copies.cpp | 285 +++++++++++++++++------------ 2 files changed, 246 insertions(+), 120 deletions(-) create mode 100644 tests/ChunkBuffer/ArraytoCoord.cpp diff --git a/tests/ChunkBuffer/ArraytoCoord.cpp b/tests/ChunkBuffer/ArraytoCoord.cpp new file mode 100644 index 000000000..a765c5302 --- /dev/null +++ b/tests/ChunkBuffer/ArraytoCoord.cpp @@ -0,0 +1,81 @@ + +#include "TestGlobals.h" +#include "ChunkBuffer.h" + + + +int main(int argc, char** argv) +{ + { + cChunkBuffer buffer; + + BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); + SrcBlockBuffer[7+4*16+5*16*16] = 0xCD; + buffer.SetBlocks(SrcBlockBuffer); + testassert(buffer.GetBlock(7,5,4) == 0xCD); + delete SrcBlockBuffer; + SrcBlockBuffer = NULL; + + NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + SrcNibbleBuffer[(6+1*16+2*16*16)/2] = 0xE; + buffer.SetMeta(SrcNibbleBuffer); + testassert(buffer.GetMeta(6,2,1) == 0xE); + delete SrcNibbleBuffer; + SrcNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + SrcNibbleBuffer[(6+1*16+2*16*16)/2] = 0xE; + buffer.SetLight(SrcNibbleBuffer); + testassert(buffer.GetBlockLight(6,2,1) == 0xE); + delete SrcNibbleBuffer; + SrcNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + SrcNibbleBuffer[(6+1*16+2*16*16)/2] = 0xE; + buffer.SetSkyLight(SrcNibbleBuffer); + testassert(buffer.GetSkyLight(6,2,1) == 0xE); + delete SrcNibbleBuffer; + SrcNibbleBuffer = NULL; + } + + { + cChunkBuffer buffer; + + BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); + SrcBlockBuffer[7+4*16+24*16*16] = 0xCD; + buffer.SetBlocks(SrcBlockBuffer); + testassert(buffer.GetBlock(7,24,4) == 0xCD); + delete SrcBlockBuffer; + SrcBlockBuffer = NULL; + + NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + SrcNibbleBuffer[(6+1*16+24*16*16)/2] = 0xE; + buffer.SetMeta(SrcNibbleBuffer); + testassert(buffer.GetMeta(6,24,1) == 0xE); + delete SrcNibbleBuffer; + SrcNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + SrcNibbleBuffer[(6+1*16+24*16*16)/2] = 0xE; + buffer.SetLight(SrcNibbleBuffer); + testassert(buffer.GetBlockLight(6,24,1) == 0xE); + delete SrcNibbleBuffer; + SrcNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + SrcNibbleBuffer[(6+1*16+24*16*16)/2] = 0xE; + buffer.SetSkyLight(SrcNibbleBuffer); + testassert(buffer.GetSkyLight(6,24,1) == 0xE); + delete SrcNibbleBuffer; + SrcNibbleBuffer = NULL; + } +} + diff --git a/tests/ChunkBuffer/Copies.cpp b/tests/ChunkBuffer/Copies.cpp index eb149f25f..b37414ce4 100644 --- a/tests/ChunkBuffer/Copies.cpp +++ b/tests/ChunkBuffer/Copies.cpp @@ -6,128 +6,173 @@ int main(int argc, char** argv) { - cChunkBuffer buffer; - - buffer.SetBlock(3,1,4,0xDE); - buffer.SetMeta(3,1,4,0xA); - - cChunkBuffer copy = buffer.Copy(); - testassert(copy.GetBlock(3,1,4) == 0xDE); - testassert(copy.GetMeta(3,1,4) == 0xA); - - BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[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; + cChunkBuffer buffer; + + buffer.SetBlock(3,1,4,0xDE); + buffer.SetMeta(3,1,4,0xA); + + cChunkBuffer copy = buffer.Copy(); + testassert(copy.GetBlock(3,1,4) == 0xDE); + testassert(copy.GetMeta(3,1,4) == 0xA); + + BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[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.SetBlocks(SrcBlockBuffer); + BLOCKTYPE * DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + buffer.CopyBlocks(DstBlockBuffer); + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); + delete SrcBlockBuffer; + delete DstBlockBuffer; + SrcBlockBuffer = NULL; + DstBlockBuffer = NULL; + + NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) + { + SrcNibbleBuffer[i+0] = 0xEF; + SrcNibbleBuffer[i+1] = 0xDE; + SrcNibbleBuffer[i+2] = 0xAD; + SrcNibbleBuffer[i+3] = 0xBE; + } + + buffer.SetMeta(SrcNibbleBuffer); + NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyMeta(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[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.SetLight(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) + { + SrcNibbleBuffer[i+0] = 0xAD; + SrcNibbleBuffer[i+1] = 0xBE; + SrcNibbleBuffer[i+2] = 0xEF; + SrcNibbleBuffer[i+3] = 0xDE; + } + + buffer.SetSkyLight(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopySkyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); + buffer.SetBlocks(SrcBlockBuffer); + DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + buffer.CopyBlocks(DstBlockBuffer); + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); + delete SrcBlockBuffer; + delete DstBlockBuffer; + SrcBlockBuffer = NULL; + DstBlockBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + buffer.SetMeta(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyMeta(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + buffer.SetLight(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); + buffer.SetSkyLight(SrcNibbleBuffer); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopySkyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; } - - buffer.SetBlocks(SrcBlockBuffer); - BLOCKTYPE * DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; - buffer.CopyBlocks(DstBlockBuffer); - testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); - delete SrcBlockBuffer; - delete DstBlockBuffer; - SrcBlockBuffer = NULL; - DstBlockBuffer = NULL; - - NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) { - SrcNibbleBuffer[i+0] = 0xEF; - SrcNibbleBuffer[i+1] = 0xDE; - SrcNibbleBuffer[i+2] = 0xAD; - SrcNibbleBuffer[i+3] = 0xBE; + cChunkBuffer buffer; + + BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); + BLOCKTYPE * DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + buffer.CopyBlocks(DstBlockBuffer); + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); + delete SrcBlockBuffer; + delete DstBlockBuffer; + SrcBlockBuffer = NULL; + DstBlockBuffer = NULL; + + NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyMeta(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); + DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopySkyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; } - - buffer.SetMeta(SrcNibbleBuffer); - NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopyMeta(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; - - SrcNibbleBuffer = new NIBBLETYPE[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.SetLight(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; - - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) - { - SrcNibbleBuffer[i+0] = 0xAD; - SrcNibbleBuffer[i+1] = 0xBE; - SrcNibbleBuffer[i+2] = 0xEF; - SrcNibbleBuffer[i+3] = 0xDE; - } - - buffer.SetSkyLight(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopySkyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; - - SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; - memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); - buffer.SetBlocks(SrcBlockBuffer); - DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; - buffer.CopyBlocks(DstBlockBuffer); - testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); - delete SrcBlockBuffer; - delete DstBlockBuffer; - SrcBlockBuffer = NULL; - DstBlockBuffer = NULL; - - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - buffer.SetMeta(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopyMeta(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; - - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - buffer.SetLight(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; - - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); - buffer.SetSkyLight(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopySkyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; } From c0727c426572745c72a61d26a84754d5a641d562 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 11 May 2014 22:35:41 +0200 Subject: [PATCH 048/312] Initial VillageGen implementation. WIP, doesn't generate anything yet. Ref.: 740. --- .../Prefabs/PlainsVillagePrefabs.cpp | 3726 +++++++++++++++++ src/Generating/Prefabs/PlainsVillagePrefabs.h | 15 + src/Generating/Prefabs/SandVillagePrefabs.cpp | 1887 +++++++++ src/Generating/Prefabs/SandVillagePrefabs.h | 15 + src/Generating/VillageGen.cpp | 116 + src/Generating/VillageGen.h | 48 + 6 files changed, 5807 insertions(+) create mode 100644 src/Generating/Prefabs/PlainsVillagePrefabs.cpp create mode 100644 src/Generating/Prefabs/PlainsVillagePrefabs.h create mode 100644 src/Generating/Prefabs/SandVillagePrefabs.cpp create mode 100644 src/Generating/Prefabs/SandVillagePrefabs.h create mode 100644 src/Generating/VillageGen.cpp create mode 100644 src/Generating/VillageGen.h diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp new file mode 100644 index 000000000..f59e22fb3 --- /dev/null +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -0,0 +1,3726 @@ + +// 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[] = +{ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Forge: + // The data has been exported from the gallery Plains, area index 51, ID 102, created by Aloe_vera + { + // Size: + 12, 8, 11, // SizeX = 12, SizeY = 8, SizeZ = 11 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 11, 7, 10, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "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 */ ".....abbbc.." + /* 1 */ ".ddddddddc.." + /* 2 */ ".ddddddddc.." + /* 3 */ ".ddddddddddd" + /* 4 */ ".ddddddddddd" + /* 5 */ ".ddddddddddd" + /* 6 */ ".ddddddddddd" + /* 7 */ ".ddddddddddd" + /* 8 */ ".ddddd.mmmmm" + /* 9 */ ".ddddd.mmmmm" + /* 10 */ ".......mmmmm" + + // Level 1 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".efffe......" + /* 2 */ ".f...g......" + /* 3 */ ".f...ed..ddd" + /* 4 */ ".f...f...dhd" + /* 5 */ ".f...f...dhd" + /* 6 */ ".f...fijjdhd" + /* 7 */ ".f...edddddd" + /* 8 */ ".f...f.mmmmm" + /* 9 */ ".efffe.mmmmm" + /* 10 */ ".......mmmmm" + + // Level 2 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".ekkke......" + /* 2 */ ".k...l......" + /* 3 */ ".k...en..n.d" + /* 4 */ ".k...k.....o" + /* 5 */ ".f...k.....o" + /* 6 */ ".k...k.....o" + /* 7 */ ".k...edooood" + /* 8 */ ".k...f.mmmmm" + /* 9 */ ".ekkke.mmmmm" + /* 10 */ ".......mmmmm" + + // Level 3 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "ppppppp....." + /* 1 */ "qfffffq....." + /* 2 */ ".f...f......" + /* 3 */ ".f..rfd..dod" + /* 4 */ ".f...f...o.d" + /* 5 */ ".f...f...o.d" + /* 6 */ ".fs..f...o.d" + /* 7 */ ".f...fdddddd" + /* 8 */ ".f...f.mmmmm" + /* 9 */ "tffffftmmmmm" + /* 10 */ "uuuuuuummmmm" + + // Level 4 + /* 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 */ "tffffftmmmmm" + /* 9 */ "uuuuuuummmmm" + /* 10 */ ".......mmmmm" + + // Level 5 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "ppppppp....." + /* 3 */ "qfffffq....." + /* 4 */ ".f...f......" + /* 5 */ ".f...f......" + /* 6 */ ".f...f......" + /* 7 */ "tffffft....." + /* 8 */ "uuuuuuummmmm" + /* 9 */ ".......mmmmm" + /* 10 */ ".......mmmmm" + + // Level 6 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "............" + /* 3 */ "ppppppp....." + /* 4 */ "qfffffq....." + /* 5 */ ".f...f......" + /* 6 */ "tffffft....." + /* 7 */ "uuuuuuu....." + /* 8 */ ".......mmmmm" + /* 9 */ ".......mmmmm" + /* 10 */ ".......mmmmm" + + // Level 7 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "............" + /* 3 */ "............" + /* 4 */ "ppppppp....." + /* 5 */ "fffffff....." + /* 6 */ "uuuuuuu....." + /* 7 */ "............" + /* 8 */ ".......mmmmm" + /* 9 */ ".......mmmmm" + /* 10 */ ".......mmmmm", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // Forge + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_100: + // The data has been exported from the gallery Plains, area index 49, ID 100, 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: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 17: 0\n" /* tree */ + "f: 5: 0\n" /* wood */ + "g: 64: 5\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 */ "..abc.." + /* 1 */ ".ddddd." + /* 2 */ ".ddddd." + /* 3 */ ".ddddd." + /* 4 */ ".ddddd." + /* 5 */ ".ddddd." + /* 6 */ "......." + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".efgfe." + /* 2 */ ".f...f." + /* 3 */ ".f...f." + /* 4 */ ".f...f." + /* 5 */ ".efffe." + /* 6 */ "......." + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".efhfe." + /* 2 */ ".i...i." + /* 3 */ ".i...i." + /* 4 */ ".i...i." + /* 5 */ ".eiiie." + /* 6 */ "......." + + // Level 3 + /* z\x* 0123456 */ + /* 0 */ "jjjjjjj" + /* 1 */ "kfffffk" + /* 2 */ ".fl.lf." + /* 3 */ ".f...f." + /* 4 */ ".f...f." + /* 5 */ "nfffffn" + /* 6 */ "ooooooo" + + // Level 4 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ "jjjjjjj" + /* 2 */ "kfffffk" + /* 3 */ ".f...f." + /* 4 */ "nfffffn" + /* 5 */ "ooooooo" + /* 6 */ "......." + + // Level 5 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ "......." + /* 2 */ "jjjjjjj" + /* 3 */ "fffffff" + /* 4 */ "ooooooo" + /* 5 */ "......." + /* 6 */ ".......", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_100 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_103: + // The data has been exported from the gallery Plains, area index 52, ID 103, created by Aloe_vera + { + // 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: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 17: 0\n" /* tree */ + "f: 5: 0\n" /* wood */ + "g: 64: 5\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 */ "....abc...." + /* 1 */ ".ddddddddd." + /* 2 */ ".ddddddddd." + /* 3 */ ".ddddddddd." + /* 4 */ ".ddddddddd." + /* 5 */ ".ddddddddd." + /* 6 */ ".ddddddddd." + /* 7 */ ".ddddddddd." + /* 8 */ "..........." + + // Level 1 + /* 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 2 + /* 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 3 + /* 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 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "jjjjjjjjjjj" + /* 2 */ "kfffffffffk" + /* 3 */ ".f.......f." + /* 4 */ ".f.......f." + /* 5 */ ".f.......f." + /* 6 */ "offfffffffo" + /* 7 */ "ppppppppppp" + /* 8 */ "..........." + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "jjjjjjjjjjj" + /* 3 */ "kfffffffffk" + /* 4 */ ".f.......f." + /* 5 */ "offfffffffo" + /* 6 */ "ppppppppppp" + /* 7 */ "..........." + /* 8 */ "..........." + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ "jjjjjjjjjjj" + /* 4 */ "fffffffffff" + /* 5 */ "ppppppppppp" + /* 6 */ "..........." + /* 7 */ "..........." + /* 8 */ "...........", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_103 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_105: + // The data has been exported from the gallery Plains, area index 54, ID 105, created by Aloe_vera + { + // Size: + 7, 6, 9, // SizeX = 7, SizeY = 6, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 5, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:170: 0\n" /* haybale */ + "b: 67: 0\n" /* stairs */ + "c: 67: 2\n" /* stairs */ + "d: 67: 1\n" /* stairs */ + "e: 4: 0\n" /* cobblestone */ + "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 */ "abcccd." + /* 1 */ ".eeeee." + /* 2 */ ".eeeee." + /* 3 */ ".eeeee." + /* 4 */ ".eeeee." + /* 5 */ ".eeeee." + /* 6 */ ".eeeee." + /* 7 */ ".eeeee." + /* 8 */ "......." + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".f..af." + /* 2 */ ".g...g." + /* 3 */ ".ga.hg." + /* 4 */ ".fihif." + /* 5 */ ".gaaag." + /* 6 */ ".gijag." + /* 7 */ ".fgfgf." + /* 8 */ "......." + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ ".k...k." + /* 1 */ ".f...f." + /* 2 */ ".g...g." + /* 3 */ ".g...g." + /* 4 */ ".fh..f." + /* 5 */ ".ghiag." + /* 6 */ ".ghiig." + /* 7 */ ".fgfgf." + /* 8 */ "......." + + // Level 3 + /* z\x* 0123456 */ + /* 0 */ "ln...op" + /* 1 */ "lgggggp" + /* 2 */ "lg...gp" + /* 3 */ "lg...gp" + /* 4 */ "lg...gp" + /* 5 */ "lgaa.gp" + /* 6 */ "lgiaigp" + /* 7 */ "lgggggp" + /* 8 */ "ln...op" + + // Level 4 + /* 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 5 + /* z\x* 0123456 */ + /* 0 */ "..lgp.." + /* 1 */ "..lgp.." + /* 2 */ "..lgp.." + /* 3 */ "..lgp.." + /* 4 */ "..lgp.." + /* 5 */ "..lgp.." + /* 6 */ "..lgp.." + /* 7 */ "..lgp.." + /* 8 */ "..lgp..", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_105 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_106: + // The data has been exported from the gallery Plains, area index 55, ID 106, created by Aloe_vera + { + // 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: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "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 */ ".abbbbbbbbbbbc." + /* 1 */ ".ddddddddddddd." + /* 2 */ ".deeeeeeeeeeed." + /* 3 */ ".deeeeeeeeeeed." + /* 4 */ ".deeeeeeeeeeed." + /* 5 */ ".deeeeeeeeeeed." + /* 6 */ ".deeeeeeeeeeed." + /* 7 */ ".ddddddddddddd." + /* 8 */ "..............." + + // Level 1 + /* 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 2 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".f...i...i...f." + /* 2 */ "..............." + /* 3 */ "..............." + /* 4 */ "..............." + /* 5 */ "..............." + /* 6 */ "..............." + /* 7 */ ".f...i...i...f." + /* 8 */ "..............." + + // Level 3 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".fp.qip.qip.qf." + /* 2 */ "..............." + /* 3 */ "..............." + /* 4 */ "..............." + /* 5 */ "..............." + /* 6 */ "..............." + /* 7 */ ".f...i...i...f." + /* 8 */ "..............." + + // Level 4 + /* 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 5 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "rrrrrrrrrrrrrrr" + /* 2 */ "siiiiiiiiiiiiis" + /* 3 */ ".i...........i." + /* 4 */ ".i...........i." + /* 5 */ ".i...........i." + /* 6 */ "tiiiiiiiiiiiiit" + /* 7 */ "uuuuuuuuuuuuuuu" + /* 8 */ "..............." + + // Level 6 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "..............." + /* 2 */ "rrrrrrrrrrrrrrr" + /* 3 */ "siiiiiiiiiiiiis" + /* 4 */ ".i...........i." + /* 5 */ "tiiiiiiiiiiiiit" + /* 6 */ "uuuuuuuuuuuuuuu" + /* 7 */ "..............." + /* 8 */ "..............." + + // Level 7 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "..............." + /* 2 */ "..............." + /* 3 */ "rrrrrrrrrrrrrrr" + /* 4 */ "iiiiiiiiiiiiiii" + /* 5 */ "uuuuuuuuuuuuuuu" + /* 6 */ "..............." + /* 7 */ "..............." + /* 8 */ "...............", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_106 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_109: + // The data has been exported from the gallery Plains, area index 58, ID 109, created by Aloe_vera + { + // Size: + 7, 14, 13, // SizeX = 7, SizeY = 14, SizeZ = 13 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 13, 12, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "A: 85: 0\n" /* fence */ + "B:126: 8\n" /* woodenslab */ + "a: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "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 */ "..abc.." + /* 1 */ ".ddddd." + /* 2 */ ".ddddd." + /* 3 */ ".ddddd." + /* 4 */ ".ddddd." + /* 5 */ ".ddddd." + /* 6 */ ".ddddd." + /* 7 */ ".ddddd." + /* 8 */ ".ddddd." + /* 9 */ ".ddddd." + /* 10 */ ".ddddd." + /* 11 */ ".ddddd." + /* 12 */ "......." + + // Level 1 + /* 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 2 + /* 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 3 + /* 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 */ "sefffft" + /* 12 */ "su...vt" + + // Level 4 + /* 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 5 + /* 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 6 + /* 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 7 + /* 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 8 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ewwwe." + /* 2 */ ".xffhx." + /* 3 */ ".xfffx." + /* 4 */ ".xfffx." + /* 5 */ ".ewwwe." + /* 6 */ "......." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 9 + /* 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 10 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".e...e." + /* 2 */ "......." + /* 3 */ "......." + /* 4 */ "......." + /* 5 */ ".e...e." + /* 6 */ "......." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 11 + /* z\x* 0123456 */ + /* 0 */ "su...vt" + /* 1 */ "sefffet" + /* 2 */ "sfBBBft" + /* 3 */ "sfBBBft" + /* 4 */ "sfBBBft" + /* 5 */ "sffffft" + /* 6 */ "su...vt" + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 12 + /* 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 13 + /* z\x* 0123456 */ + /* 0 */ "..sft.." + /* 1 */ "..sft.." + /* 2 */ "..sft.." + /* 3 */ "..sft.." + /* 4 */ "..sft.." + /* 5 */ "..sft.." + /* 6 */ "..sft.." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ ".......", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_109 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_20: + // The data has been exported from the gallery Plains, area index 5, ID 20, created by tonibm1999 + { + // Size: + 15, 2, 9, // SizeX = 15, SizeY = 2, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 14, 1, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 17: 0\n" /* tree */ + "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* 11111 */ + /* * 012345678901234 */ + /* 0 */ "aaaaaaamaaaaaaa" + /* 1 */ "abbcbbamabbcbba" + /* 2 */ "abbcbbamabbcbba" + /* 3 */ "abbcbbamabbcbba" + /* 4 */ "abbcbbamabbcbba" + /* 5 */ "abbcbbamabbcbba" + /* 6 */ "abbcbbamabbcbba" + /* 7 */ "abbcbbamabbcbba" + /* 8 */ "aaaaaaamaaaaaaa" + + // Level 1 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "dmmmmmdmdmmmmmd" + /* 1 */ "meemeemmmeemeem" + /* 2 */ "memmmemmmeemeem" + /* 3 */ "memmmmmmmeemeem" + /* 4 */ "meemmemmmeemeem" + /* 5 */ "meemmemmmeemeem" + /* 6 */ "mmemmemmmeemeem" + /* 7 */ "mmememmmmeemeem" + /* 8 */ "dmmmmmdmdmmmmmd", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_20 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_26: + // The data has been exported from the gallery Plains, area index 9, ID 26, created by Aloe_vera + { + // Size: + 10, 6, 11, // SizeX = 10, SizeY = 6, SizeZ = 11 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 9, 5, 10, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 4: 0\n" /* cobblestone */ + "b: 5: 0\n" /* wood */ + "c: 2: 0\n" /* grass */ + "d: 67: 2\n" /* stairs */ + "e: 43: 0\n" /* doubleslab */ + "f: 67: 0\n" /* stairs */ + "g: 67: 3\n" /* stairs */ + "h: 17: 0\n" /* tree */ + "i: 53: 1\n" /* woodstairs */ + "j: 85: 0\n" /* fence */ + "k: 53: 0\n" /* woodstairs */ + "l: 64: 4\n" /* wooddoorblock */ + "m: 19: 0\n" /* sponge */ + "n: 64: 0\n" /* wooddoorblock */ + "o:102: 0\n" /* glasspane */ + "p: 72: 0\n" /* woodplate */ + "q: 64:12\n" /* wooddoorblock */ + "r: 64: 8\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 */ "......mmmm" + /* 1 */ ".aaaaammmm" + /* 2 */ ".abbbammmm" + /* 3 */ ".abbbacccc" + /* 4 */ "daeeeacccc" + /* 5 */ "faeeeecccc" + /* 6 */ "gaeeeacccc" + /* 7 */ ".aeeeacccc" + /* 8 */ ".aeeeacccc" + /* 9 */ ".aaaaammmm" + /* 10 */ "......mmmm" + + // Level 1 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "......mmmm" + /* 1 */ ".hbbbhmmmm" + /* 2 */ ".bijkbmmmm" + /* 3 */ ".b...bjjjj" + /* 4 */ ".b...b...j" + /* 5 */ ".l...n...j" + /* 6 */ ".b...b...j" + /* 7 */ ".bee.b...j" + /* 8 */ ".b...bjjjj" + /* 9 */ ".hbbbhmmmm" + /* 10 */ "......mmmm" + + // Level 2 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "......mmmm" + /* 1 */ ".hooohmmmm" + /* 2 */ ".o.p.ommmm" + /* 3 */ ".o...o...." + /* 4 */ ".b...b...." + /* 5 */ ".q...r...." + /* 6 */ ".b...b...." + /* 7 */ ".o...o...." + /* 8 */ ".o...o...." + /* 9 */ ".hooohmmmm" + /* 10 */ "......mmmm" + + // Level 3 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "ks...timmm" + /* 1 */ "khbbbhimmm" + /* 2 */ "kb...bimmm" + /* 3 */ "kb...bi..." + /* 4 */ "kbu.vbi..." + /* 5 */ "kb...bi..." + /* 6 */ "kbu.vbi..." + /* 7 */ "kb...bi..." + /* 8 */ "kb...bi..." + /* 9 */ "khbbbhimmm" + /* 10 */ "ks...timmm" + + // Level 4 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "mks.timmmm" + /* 1 */ "mkbbbimmmm" + /* 2 */ "mkb.bimmmm" + /* 3 */ "mkb.bim..." + /* 4 */ "mkb.bim..." + /* 5 */ "mkb.bim..." + /* 6 */ "mkb.bim..." + /* 7 */ "mkb.bim..." + /* 8 */ "mkb.bim..." + /* 9 */ "mkbbbimmmm" + /* 10 */ "mks.timmmm" + + // Level 5 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "mmkbimmmmm" + /* 1 */ "mmkbimmmmm" + /* 2 */ "mmkbimmmmm" + /* 3 */ "mmkbimm..." + /* 4 */ "mmkbimm..." + /* 5 */ "mmkbimm..." + /* 6 */ "mmkbimm..." + /* 7 */ "mmkbimm..." + /* 8 */ "mmkbimm..." + /* 9 */ "mmkbimmmmm" + /* 10 */ "mmkbimmmmm", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_26 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_4: + // The data has been exported from the gallery Plains, area index 0, ID 4, 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: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 5: 0\n" /* wood */ + "f: 67: 3\n" /* stairs */ + "g: 17: 0\n" /* tree */ + "h: 64: 5\n" /* wooddoorblock */ + "i:102: 0\n" /* glasspane */ + "j: 64:12\n" /* wooddoorblock */ + "k: 53: 2\n" /* woodstairs */ + "l: 53: 1\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 53: 7\n" /* woodstairs */ + "o: 53: 6\n" /* woodstairs */ + "p: 53: 3\n" /* woodstairs */ + "q: 53: 0\n" /* woodstairs */ + "r: 53: 5\n" /* woodstairs */ + "s: 53: 4\n" /* woodstairs */ + "t: 50: 3\n" /* torch */ + "u: 50: 2\n" /* torch */ + "v: 50: 4\n" /* torch */ + "w: 50: 1\n" /* torch */, + + // Block data: + // Level 0 + /* z\x* 111111 */ + /* * 0123456789012345 */ + /* 0 */ "........abc....." + /* 1 */ ".dddddddddddddd." + /* 2 */ ".deeeeeeeeeeeed." + /* 3 */ ".deeeeeeeeeeeed." + /* 4 */ ".deeeeeeeeeeeed." + /* 5 */ ".deeeeeeeeeeeed." + /* 6 */ ".deeeeeeeeeeeed." + /* 7 */ ".ddddddddeeeeed." + /* 8 */ "mmmmmafcdeeeeed." + /* 9 */ "mmmmmmmmdeeeeed." + /* 10 */ "mmmmmmmmdeeeeed." + /* 11 */ "mmmmmmmmdeeeeed." + /* 12 */ "mmmmmmmmdeeeeed." + /* 13 */ "mmmmmmmmdeeeeed." + /* 14 */ "mmmmmmmmddddddd." + /* 15 */ "mmmmmmmm........" + + // Level 1 + /* z\x* 111111 */ + /* * 0123456789012345 */ + /* 0 */ "................" + /* 1 */ ".geeeeeeghgeeeg." + /* 2 */ ".e............e." + /* 3 */ ".e............e." + /* 4 */ ".e............e." + /* 5 */ ".e............e." + /* 6 */ ".e............e." + /* 7 */ ".geeeeheg.....e." + /* 8 */ "mmmmmm.me.....e." + /* 9 */ "mmmmmmmme.....e." + /* 10 */ "mmmmmmmme.....e." + /* 11 */ "mmmmmmmme.....e." + /* 12 */ "mmmmmmmme.....e." + /* 13 */ "mmmmmmmme.....e." + /* 14 */ "mmmmmmmmgeeeeeg." + /* 15 */ "mmmmmmmm........" + + // Level 2 + /* z\x* 111111 */ + /* * 0123456789012345 */ + /* 0 */ "................" + /* 1 */ ".geiieiigjgiieg." + /* 2 */ ".i............e." + /* 3 */ ".i............i." + /* 4 */ ".i............i." + /* 5 */ ".i............e." + /* 6 */ ".i............i." + /* 7 */ ".geiiejeg.....i." + /* 8 */ "mmmmmm.me.....e." + /* 9 */ "mmmmmmmmi.....i." + /* 10 */ "mmmmmmmmi.....i." + /* 11 */ "mmmmmmmme.....e." + /* 12 */ "mmmmmmmmi.....i." + /* 13 */ "mmmmmmmmi.....i." + /* 14 */ "mmmmmmmmgiiiiig." + /* 15 */ "mmmmmmmm........" + + // Level 3 + /* z\x* 111111 */ + /* * 0123456789012345 */ + /* 0 */ "kkkkkkkkkkkkkkkl" + /* 1 */ "ngeeeeeegegeeegl" + /* 2 */ ".e............el" + /* 3 */ ".e............el" + /* 4 */ ".e............el" + /* 5 */ ".e............el" + /* 6 */ ".e............el" + /* 7 */ "ogeeeeeeg.....el" + /* 8 */ "pppppppqe.....el" + /* 9 */ "mmmmmmmqe.....el" + /* 10 */ "mmmmmmmqe.....el" + /* 11 */ "mmmmmmmqe.....el" + /* 12 */ "mmmmmmmqe.....el" + /* 13 */ "mmmmmmmqe.....el" + /* 14 */ "mmmmmmmqgeeeeegl" + /* 15 */ "mmmmmmmqr.....sl" + + // Level 4 + /* z\x* 111111 */ + /* * 0123456789012345 */ + /* 0 */ "................" + /* 1 */ "kkkkkkkkkkkkkkk." + /* 2 */ "neeeeeeeeeeeeel." + /* 3 */ ".e.........t.el." + /* 4 */ ".e..........uel." + /* 5 */ ".e......v....el." + /* 6 */ "oeeeeeeeee...el." + /* 7 */ "ppppppppqew..el." + /* 8 */ "mmmmmmmmqe...el." + /* 9 */ "mmmmmmmmqe...el." + /* 10 */ "mmmmmmmmqe...el." + /* 11 */ "mmmmmmmmqe...el." + /* 12 */ "mmmmmmmmqe...el." + /* 13 */ "mmmmmmmmqe...el." + /* 14 */ "mmmmmmmmqeeeeel." + /* 15 */ "mmmmmmmmqr...sl." + + // Level 5 + /* z\x* 111111 */ + /* * 0123456789012345 */ + /* 0 */ "................" + /* 1 */ "................" + /* 2 */ "kkkkkkkkkkkkkl.." + /* 3 */ "neeeeeeeeeeeel.." + /* 4 */ ".ew.........el.." + /* 5 */ "oeeeeeeeeee.el.." + /* 6 */ "pppppppppqe.el.." + /* 7 */ ".........qe.el.." + /* 8 */ "mmmmmmmm.qe.el.." + /* 9 */ "mmmmmmmm.qe.el.." + /* 10 */ "mmmmmmmm.qe.el.." + /* 11 */ "mmmmmmmm.qe.el.." + /* 12 */ "mmmmmmmm.qe.el.." + /* 13 */ "mmmmmmmm.qevel.." + /* 14 */ "mmmmmmmm.qeeel.." + /* 15 */ "mmmmmmmm.qr.sl.." + + // Level 6 + /* z\x* 111111 */ + /* * 0123456789012345 */ + /* 0 */ "................" + /* 1 */ "................" + /* 2 */ "................" + /* 3 */ "kkkkkkkkkkkkk..." + /* 4 */ "eeeeeeeeeeeel..." + /* 5 */ "ppppppppppqel..." + /* 6 */ "mmmmmmmmmmqel..." + /* 7 */ "mmmmmmmmmmqel..." + /* 8 */ "mmmmmmmmmmqel..." + /* 9 */ "mmmmmmmmmmqel..." + /* 10 */ "mmmmmmmmmmqel..." + /* 11 */ "mmmmmmmmmmqel..." + /* 12 */ "mmmmmmmmmmqel..." + /* 13 */ "mmmmmmmmmmqel..." + /* 14 */ "mmmmmmmmmmqel..." + /* 15 */ "mmmmmmmmmmqel...", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_4 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_60: + // The data has been exported from the gallery Plains, area index 17, ID 60, 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: 17: 0\n" /* tree */ + "b: 60: 7\n" /* tilleddirt */ + "c: 8: 0\n" /* water */ + "d: 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 */ ".........." + /* 1 */ ".dddddddd." + /* 2 */ ".dddddddd." + /* 3 */ ".........." + /* 4 */ ".dddddddd." + /* 5 */ ".dddddddd." + /* 6 */ "..........", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_60 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_66: + // 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): + 0, 0, 0, // MinX, MinY, MinZ + 11, 6, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 2: 0\n" /* grass */ + "b: 3: 0\n" /* dirt */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 64: 1\n" /* wooddoorblock */ + "h: 53: 3\n" /* woodstairs */ + "i: 53: 1\n" /* woodstairs */ + "j: 85: 0\n" /* fence */ + "k: 53: 0\n" /* woodstairs */ + "l: 53: 2\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n:102: 0\n" /* glasspane */ + "o: 64: 8\n" /* wooddoorblock */ + "p: 50: 3\n" /* torch */ + "q: 72: 0\n" /* woodplate */ + "r: 50: 4\n" /* torch */ + "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 */ + "x: 5: 0\n" /* wood */, + + // Block data: + // Level 0 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "aaaaaaabbbaa" + /* 1 */ "abbbbbbbbbba" + /* 2 */ "abbbbbbbbbba" + /* 3 */ "abbbbbbbbbba" + /* 4 */ "abbbbbbbbbba" + /* 5 */ "abbbbbbbbbba" + /* 6 */ "aaaaaaaaaaaa" + + // Level 1 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ ".......cde.." + /* 1 */ ".ffffffffff." + /* 2 */ ".ffffffffff." + /* 3 */ ".ffffffffff." + /* 4 */ ".ffffffffff." + /* 5 */ ".ffffffffff." + /* 6 */ "............" + + // Level 2 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".fffffffgff." + /* 2 */ ".fh.ijk...f." + /* 3 */ ".fj.......f." + /* 4 */ ".fl.ijkijkf." + /* 5 */ ".ffffffffff." + /* 6 */ "............" + + // Level 3 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".fnnfnnfoff." + /* 2 */ ".n..pq.p.pn." + /* 3 */ ".nq.......n." + /* 4 */ ".n..rq.rq.n." + /* 5 */ ".fnnfnnfnnf." + /* 6 */ "............" + + // Level 4 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "llllllllllll" + /* 1 */ "sffffffffffs" + /* 2 */ ".fttttttttf." + /* 3 */ ".fu......vf." + /* 4 */ ".fttttttttf." + /* 5 */ "wffffffffffw" + /* 6 */ "hhhhhhhhhhhh" + + // Level 5 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "llllllllllll" + /* 2 */ "sxxxxxxxxxxs" + /* 3 */ ".xxxxxxxxxx." + /* 4 */ "wxxxxxxxxxxw" + /* 5 */ "hhhhhhhhhhhh" + /* 6 */ "............" + + // Level 6 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "llllllllllll" + /* 3 */ "xxxxxxxxxxxx" + /* 4 */ "hhhhhhhhhhhh" + /* 5 */ "............" + /* 6 */ "............", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_66 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_87: + // The data has been exported from the gallery Plains, area index 38, ID 87, created by Aloe_vera + { + // 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: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 67: 3\n" /* stairs */ + "f: 17: 0\n" /* tree */ + "g: 5: 0\n" /* wood */ + "h: 64: 5\n" /* wooddoorblock */ + "i: 64: 7\n" /* wooddoorblock */ + "j:102: 0\n" /* glasspane */ + "k: 64:12\n" /* wooddoorblock */ + "l: 53: 2\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 53: 7\n" /* woodstairs */ + "o: 17: 4\n" /* tree */ + "p: 17: 8\n" /* tree */ + "q: 50: 3\n" /* torch */ + "r: 50: 4\n" /* torch */ + "s: 53: 6\n" /* woodstairs */ + "t: 53: 3\n" /* woodstairs */, + + // 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 */ "....aec...." + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".fggfhfggf." + /* 2 */ ".g.......g." + /* 3 */ ".g.......g." + /* 4 */ ".f.......f." + /* 5 */ ".g.......g." + /* 6 */ ".g.......g." + /* 7 */ ".fggfifggf." + /* 8 */ "..........." + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".fjjfkfjjf." + /* 2 */ ".j.......j." + /* 3 */ ".j.......j." + /* 4 */ ".f.......f." + /* 5 */ ".j.......j." + /* 6 */ ".j.......j." + /* 7 */ ".fjjfkfjjf." + /* 8 */ "..........." + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "lllllllllll" + /* 1 */ "nfooooooofn" + /* 2 */ ".p..q.q..p." + /* 3 */ ".p.......p." + /* 4 */ ".p.......p." + /* 5 */ ".p.......p." + /* 6 */ ".p..r.r..p." + /* 7 */ "sfooooooofs" + /* 8 */ "ttttttttttt" + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "lllllllllll" + /* 2 */ "ngggggggggn" + /* 3 */ ".g.......g." + /* 4 */ ".g.......g." + /* 5 */ ".g.......g." + /* 6 */ "sgggggggggs" + /* 7 */ "ttttttttttt" + /* 8 */ "..........." + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "lllllllllll" + /* 3 */ "ngggggggggn" + /* 4 */ ".g.......g." + /* 5 */ "sgggggggggs" + /* 6 */ "ttttttttttt" + /* 7 */ "..........." + /* 8 */ "..........." + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ "lllllllllll" + /* 4 */ "ggggggggggg" + /* 5 */ "ttttttttttt" + /* 6 */ "..........." + /* 7 */ "..........." + /* 8 */ "...........", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_87 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_90: + // The data has been exported from the gallery Plains, area index 39, ID 90, created by STR_Warrior + { + // Size: + 15, 8, 16, // SizeX = 15, SizeY = 8, SizeZ = 16 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 14, 7, 15, // 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: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "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 */ "......abc......" + /* 1 */ ".ddddddddddddd." + /* 2 */ ".deeeedddddddd." + /* 3 */ ".deeeedddddddd." + /* 4 */ ".ddddddddddddd." + /* 5 */ ".ddddddddddddd." + /* 6 */ ".ddddddddddddd." + /* 7 */ "mddddddddddddd." + /* 8 */ "mmmmmmmmdddddd." + /* 9 */ "mmmmmmmmdddddd." + /* 10 */ "mmmmmmmmdddddd." + /* 11 */ "mmmmmmmmdddddd." + /* 12 */ "mmmmmmmmdddddd." + /* 13 */ "mmmmmmmmdddddd." + /* 14 */ "mmmmmmmmdddddd." + /* 15 */ "mmmmmmmm......." + + // Level 1 + /* 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 */ "mfggggggfn...f." + /* 8 */ "mmmmmmmmg....g." + /* 9 */ "mmmmmmmmgk...g." + /* 10 */ "mmmmmmmmgl..kg." + /* 11 */ "mmmmmmmmgn..lg." + /* 12 */ "mmmmmmmmg...ng." + /* 13 */ "mmmmmmmmgq..qg." + /* 14 */ "mmmmmmmmfggggf." + /* 15 */ "mmmmmmmm......." + + // Level 2 + /* 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 */ "mfgrrrrgf....f." + /* 8 */ "mmmmmmmmg....g." + /* 9 */ "mmmmmmmmr....r." + /* 10 */ "mmmmmmmmrt...r." + /* 11 */ "mmmmmmmmr...tr." + /* 12 */ "mmmmmmmmr....r." + /* 13 */ "mmmmmmmmgq..qg." + /* 14 */ "mmmmmmmmfgrrgf." + /* 15 */ "mmmmmmmm......." + + // Level 3 + /* 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 */ "mfuuuuuufx..zv." + /* 8 */ "mmmmmmmmv....v." + /* 9 */ "mmmmmmmmv....v." + /* 10 */ "mmmmmmmmv....v." + /* 11 */ "mmmmmmmmv....v." + /* 12 */ "mmmmmmmmv....v." + /* 13 */ "mmmmmmmmv.yy.v." + /* 14 */ "mmmmmmmmfuuuuf." + /* 15 */ "mmmmmmmm......." + + // Level 4 + /* 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 5 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "mmmmmmmmmmmmmmm" + /* 1 */ "mpnnnnnnnnnnnom" + /* 2 */ "mpgggggggggggom" + /* 3 */ "mpgggggggggggom" + /* 4 */ "mpgggggggggggom" + /* 5 */ "mpgggggggggggom" + /* 6 */ "mpgggggggggggom" + /* 7 */ "mpkkkkkkkggggom" + /* 8 */ "mmmmmmmmpggggom" + /* 9 */ "mmmmmmmmpggggom" + /* 10 */ "mmmmmmmmpggggom" + /* 11 */ "mmmmmmmmpggggom" + /* 12 */ "mmmmmmmmpggggom" + /* 13 */ "mmmmmmmmpggggom" + /* 14 */ "mmmmmmmmkkkkkom" + /* 15 */ "mmmmmmmmmmmmmmm" + + // Level 6 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "mmmmmmmmmmmmmmm" + /* 1 */ "mmmmmmmmmmmmmmm" + /* 2 */ "mmnnnnnnnnnnnmm" + /* 3 */ "mmpgggggggggomm" + /* 4 */ "mmpgggggggggomm" + /* 5 */ "mmpgggggggggomm" + /* 6 */ "mmkkkkkkkkggomm" + /* 7 */ "mmmmmmmmmpggomm" + /* 8 */ "mmmmmmmmmpggomm" + /* 9 */ "mmmmmmmmmpggomm" + /* 10 */ "mmmmmmmmmpggomm" + /* 11 */ "mmmmmmmmmpggomm" + /* 12 */ "mmmmmmmmmpggomm" + /* 13 */ "mmmmmmmmmkkkomm" + /* 14 */ "mmmmmmmmmmmmmmm" + /* 15 */ "mmmmmmmmmmmmmmm" + + // Level 7 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "mmmmmmmmmmmmmmm" + /* 1 */ "mmmmmmmmmmmmmmm" + /* 2 */ "mmmmmmmmmmmmmmm" + /* 3 */ "mmmpnnnnnnnommm" + /* 4 */ "mmmpgggggggommm" + /* 5 */ "mmmpkkkkkkpommm" + /* 6 */ "mmmmmmmmmmpommm" + /* 7 */ "mmmmmmmmmmpommm" + /* 8 */ "mmmmmmmmmmpommm" + /* 9 */ "mmmmmmmmmmpommm" + /* 10 */ "mmmmmmmmmmpommm" + /* 11 */ "mmmmmmmmmmpommm" + /* 12 */ "mmmmmmmmmmpkmmm" + /* 13 */ "mmmmmmmmmmmmmmm" + /* 14 */ "mmmmmmmmmmmmmmm" + /* 15 */ "mmmmmmmmmmmmmmm", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_90 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_91: + // 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): + 0, 0, 0, // MinX, MinY, MinZ + 8, 6, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 2: 0\n" /* grass */ + "b: 3: 0\n" /* dirt */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 5\n" /* wooddoorblock */ + "j:102: 0\n" /* glasspane */ + "k: 64:12\n" /* wooddoorblock */ + "l: 53: 2\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 53: 7\n" /* woodstairs */ + "o: 50: 3\n" /* torch */ + "p: 53: 6\n" /* woodstairs */ + "q: 53: 3\n" /* woodstairs */, + + // Block data: + // Level 0 + /* z\x* 012345678 */ + /* 0 */ "aaabbbaaa" + /* 1 */ "abbbbbbba" + /* 2 */ "abbbbbbba" + /* 3 */ "abbbbbbba" + /* 4 */ "abbbbbbba" + /* 5 */ "abbbbbbba" + /* 6 */ "aaaaaaaaa" + + // Level 1 + /* z\x* 012345678 */ + /* 0 */ "...cde..." + /* 1 */ ".fffffff." + /* 2 */ ".fffffff." + /* 3 */ ".fffffff." + /* 4 */ ".fffffff." + /* 5 */ ".fffffff." + /* 6 */ "........." + + // Level 2 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ ".ghhihhg." + /* 2 */ ".h.....h." + /* 3 */ ".h.....h." + /* 4 */ ".h.....h." + /* 5 */ ".ghhhhhg." + /* 6 */ "........." + + // Level 3 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ ".gjhkhjg." + /* 2 */ ".j.....j." + /* 3 */ ".j.....j." + /* 4 */ ".j.....j." + /* 5 */ ".gjjhjjg." + /* 6 */ "........." + + // Level 4 + /* z\x* 012345678 */ + /* 0 */ "lllllllll" + /* 1 */ "nghhhhhgn" + /* 2 */ ".h.o.o.h." + /* 3 */ ".h.....h." + /* 4 */ ".h.....h." + /* 5 */ "pghhhhhgp" + /* 6 */ "qqqqqqqqq" + + // Level 5 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "lllllllll" + /* 2 */ "nhhhhhhhn" + /* 3 */ ".h.....h." + /* 4 */ "phhhhhhhp" + /* 5 */ "qqqqqqqqq" + /* 6 */ "........." + + // Level 6 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "lllllllll" + /* 3 */ "hhhhhhhhh" + /* 4 */ "qqqqqqqqq" + /* 5 */ "........." + /* 6 */ ".........", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_91 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_92: + // The data has been exported from the gallery Plains, area index 41, ID 92, created by xoft + { + // 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: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 17: 0\n" /* tree */ + "f: 5: 0\n" /* wood */ + "g: 64: 5\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 */ "....abc...." + /* 1 */ ".ddddddddd." + /* 2 */ ".ddddddddd." + /* 3 */ ".ddddddddd." + /* 4 */ ".ddddddddd." + /* 5 */ ".ddddddddd." + /* 6 */ "..........." + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".efffgfffe." + /* 2 */ ".f.......f." + /* 3 */ ".f.......f." + /* 4 */ ".f.......f." + /* 5 */ ".efffffffe." + /* 6 */ "..........." + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".ehhfifhhe." + /* 2 */ ".h.......h." + /* 3 */ ".h.......h." + /* 4 */ ".h.......h." + /* 5 */ ".ehhhfhhhe." + /* 6 */ "..........." + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "jjjjjjjjjjj" + /* 1 */ "kfffffffffk" + /* 2 */ ".f..l.l.ff." + /* 3 */ ".f......ff." + /* 4 */ ".f......ff." + /* 5 */ "nfffffffffn" + /* 6 */ "ooooooooooo" + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "jjjjjjjjjjj" + /* 2 */ "kfffffffffk" + /* 3 */ ".fffffffff." + /* 4 */ "nfffffffffn" + /* 5 */ "ooooooooooo" + /* 6 */ "..........." + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "jjjjjjjjjjj" + /* 3 */ "fffffffffff" + /* 4 */ "ooooooooooo" + /* 5 */ "..........." + /* 6 */ "...........", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_92 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_93: + // The data has been exported from the gallery Plains, area index 42, ID 93, created by xoft + { + // Size: + 11, 6, 11, // SizeX = 11, SizeY = 6, SizeZ = 11 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 5, 10, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 17: 0\n" /* tree */ + "f: 5: 0\n" /* wood */ + "g: 64: 5\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 */ "....abc...." + /* 1 */ ".ddddddddd." + /* 2 */ ".ddddddddd." + /* 3 */ ".ddddddddd." + /* 4 */ ".ddddddddd." + /* 5 */ ".ddddddddd." + /* 6 */ ".....ddddd." + /* 7 */ "mmmm.ddddd." + /* 8 */ "mmmm.ddddd." + /* 9 */ "mmmm.ddddd." + /* 10 */ "mmmm......." + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".efffgfffe." + /* 2 */ ".f.......f." + /* 3 */ ".f.......f." + /* 4 */ ".f.......f." + /* 5 */ ".efffe...f." + /* 6 */ ".....f...f." + /* 7 */ "mmmm.f...f." + /* 8 */ "mmmm.f...f." + /* 9 */ "mmmm.efffe." + /* 10 */ "mmmm......." + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".ehhfifhhe." + /* 2 */ ".h.......h." + /* 3 */ ".h.......h." + /* 4 */ ".h.......h." + /* 5 */ ".ehhhe...f." + /* 6 */ ".....h...h." + /* 7 */ "mmmm.h...h." + /* 8 */ "mmmm.h...h." + /* 9 */ "mmmm.ehhhe." + /* 10 */ "mmmm......." + + // Level 3 + /* 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 */ "mmmmtf...fl" + /* 8 */ "mmmmtf...fl" + /* 9 */ "mmmmtfffffl" + /* 10 */ "mmmmtu...vl" + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "jjjjjjjjjl." + /* 2 */ "kffffffffl." + /* 3 */ ".f......fl." + /* 4 */ "pffffff.fl." + /* 5 */ "ssssssf.fl." + /* 6 */ ".....tf.fl." + /* 7 */ "mmmm.tf.fl." + /* 8 */ "mmmm.tf.fl." + /* 9 */ "mmmm.tfffl." + /* 10 */ "mmmm.tu.vl." + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "jjjjjjjjj.." + /* 3 */ "ffffffffl.." + /* 4 */ "sssssstfl.." + /* 5 */ "......tfl.." + /* 6 */ "......tfl.." + /* 7 */ "mmmm..tfl.." + /* 8 */ "mmmm..tfl.." + /* 9 */ "mmmm..tfl.." + /* 10 */ "mmmm..tfl..", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_93 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_94: + // The data has been exported from the gallery Plains, area index 43, ID 94, created by xoft + { + // Size: + 15, 6, 11, // SizeX = 15, SizeY = 6, SizeZ = 11 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 14, 5, 10, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 17: 0\n" /* tree */ + "f: 5: 0\n" /* wood */ + "g: 64: 5\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 */ "......abc......" + /* 1 */ ".ddddddddddddd." + /* 2 */ ".ddddddddddddd." + /* 3 */ ".ddddddddddddd." + /* 4 */ ".ddddddddddddd." + /* 5 */ ".ddddddddddddd." + /* 6 */ ".ddddd...ddddd." + /* 7 */ ".ddddd...ddddd." + /* 8 */ ".ddddd...ddddd." + /* 9 */ ".ddddd...ddddd." + /* 10 */ "..............." + + // Level 1 + /* 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 2 + /* 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 3 + /* 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 4 + /* 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 5 + /* 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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_94 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_97: + // The data has been exported from the gallery Plains, area index 46, ID 97, 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: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 17: 0\n" /* tree */ + "f: 5: 0\n" /* wood */ + "g: 64: 5\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 */ "....abc...." + /* 1 */ ".ddddddddd." + /* 2 */ ".ddddddddd." + /* 3 */ ".ddddddddd." + /* 4 */ ".ddddddddd." + /* 5 */ ".ddddddddd." + /* 6 */ "..........." + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".efffgfffe." + /* 2 */ ".fh.....hf." + /* 3 */ ".fi.....if." + /* 4 */ ".fj.kil.jf." + /* 5 */ ".efffffffe." + /* 6 */ "..........." + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".ennfofnne." + /* 2 */ ".n..p.p..n." + /* 3 */ ".nq.....qn." + /* 4 */ ".n...q...n." + /* 5 */ ".ennnfnnne." + /* 6 */ "..........." + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "jjjjjjjjjjj" + /* 1 */ "rfffffffffr" + /* 2 */ ".fsssssssf." + /* 3 */ ".ft.....uf." + /* 4 */ ".fsssssssf." + /* 5 */ "vfffffffffv" + /* 6 */ "hhhhhhhhhhh" + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "jjjjjjjjjjj" + /* 2 */ "rfffffffffr" + /* 3 */ ".f.......f." + /* 4 */ "vfffffffffv" + /* 5 */ "hhhhhhhhhhh" + /* 6 */ "..........." + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "jjjjjjjjjjj" + /* 3 */ "fffffffffff" + /* 4 */ "hhhhhhhhhhh" + /* 5 */ "..........." + /* 6 */ "...........", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_97 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_98: + // The data has been exported from the gallery Plains, area index 47, ID 98, created by Aloe_vera + { + // Size: + 12, 7, 9, // SizeX = 12, SizeY = 7, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 11, 6, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 17: 0\n" /* tree */ + "f: 5: 0\n" /* wood */ + "g: 64: 5\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:13\n" /* wooddoorblock */ + "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 */ "....abbc...." + /* 1 */ ".dddddddddd." + /* 2 */ ".dddddddddd." + /* 3 */ ".dddddddddd." + /* 4 */ ".dddddddddd." + /* 5 */ ".dddddddddd." + /* 6 */ ".dddddddddd." + /* 7 */ ".dddddddddd." + /* 8 */ "............" + + // Level 1 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".efffggfffe." + /* 2 */ ".f........f." + /* 3 */ ".fh......hf." + /* 4 */ ".fi......if." + /* 5 */ ".fj......jf." + /* 6 */ ".f.kilkil.f." + /* 7 */ ".effffffffe." + /* 8 */ "............" + + // Level 2 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".ennfopfnne." + /* 2 */ ".n..q..q..n." + /* 3 */ ".n........n." + /* 4 */ ".fr......rf." + /* 5 */ ".n........n." + /* 6 */ ".n..r..r..n." + /* 7 */ ".ennfnnfnne." + /* 8 */ "............" + + // Level 3 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "jjjjjjjjjjjj" + /* 1 */ "sffffffffffs" + /* 2 */ ".fttttttttf." + /* 3 */ ".f........f." + /* 4 */ ".fu......vf." + /* 5 */ ".f........f." + /* 6 */ ".fttttttttf." + /* 7 */ "wffffffffffw" + /* 8 */ "hhhhhhhhhhhh" + + // Level 4 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "jjjjjjjjjjjj" + /* 2 */ "sffffffffffs" + /* 3 */ ".fttttttttf." + /* 4 */ ".f........f." + /* 5 */ ".fttttttttf." + /* 6 */ "wffffffffffw" + /* 7 */ "hhhhhhhhhhhh" + /* 8 */ "............" + + // Level 5 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "jjjjjjjjjjjj" + /* 3 */ "sffffffffffs" + /* 4 */ ".f........f." + /* 5 */ "wffffffffffw" + /* 6 */ "hhhhhhhhhhhh" + /* 7 */ "............" + /* 8 */ "............" + + // Level 6 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "............" + /* 3 */ "jjjjjjjjjjjj" + /* 4 */ "ffffffffffff" + /* 5 */ "hhhhhhhhhhhh" + /* 6 */ "............" + /* 7 */ "............" + /* 8 */ "............", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_98 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // PlainsVillage_99: + // The data has been exported from the gallery Plains, area index 48, ID 99, created by Aloe_vera + { + // Size: + 11, 7, 13, // SizeX = 11, SizeY = 7, SizeZ = 13 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 6, 12, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 67: 0\n" /* stairs */ + "b: 67: 2\n" /* stairs */ + "c: 67: 1\n" /* stairs */ + "d: 4: 0\n" /* cobblestone */ + "e: 43: 0\n" /* doubleslab */ + "f: 2: 0\n" /* grass */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 5\n" /* wooddoorblock */ + "j: 53: 3\n" /* woodstairs */ + "k: 85: 0\n" /* fence */ + "l: 53: 2\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 64: 7\n" /* wooddoorblock */ + "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 */ "....abc...." + /* 1 */ ".ddddddddd." + /* 2 */ ".deeeedddd." + /* 3 */ ".deeeedddd." + /* 4 */ ".deeeedddd." + /* 5 */ ".deeeedddd." + /* 6 */ ".deeeedddd." + /* 7 */ ".ddddddddd." + /* 8 */ "..fffffff.." + /* 9 */ "mmfffffffmm" + /* 10 */ "mmfffffffmm" + /* 11 */ "mmfffffffmm" + /* 12 */ "mmfffffffmm" + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".ghhhihhhg." + /* 2 */ ".h.e....jh." + /* 3 */ ".h.e....kh." + /* 4 */ ".h.e....lh." + /* 5 */ ".h.......h." + /* 6 */ ".h.......h." + /* 7 */ ".ghhhnhhhg." + /* 8 */ "..k.....k.." + /* 9 */ "mmk.....kmm" + /* 10 */ "mmk.....kmm" + /* 11 */ "mmk.....kmm" + /* 12 */ "mmkkkkkkkmm" + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".goohphoog." + /* 2 */ ".o.......o." + /* 3 */ ".o......qo." + /* 4 */ ".h.......h." + /* 5 */ ".o.......o." + /* 6 */ ".o.......o." + /* 7 */ ".goohphoog." + /* 8 */ "..........." + /* 9 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm" + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "lllllllllll" + /* 1 */ "rhhhhhhhhhr" + /* 2 */ ".h.......h." + /* 3 */ ".h.......h." + /* 4 */ ".hs.....th." + /* 5 */ ".h.......h." + /* 6 */ ".h.......h." + /* 7 */ "uhhhhhhhhhu" + /* 8 */ "jjjjjjjjjjj" + /* 9 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm" + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "lllllllllll" + /* 2 */ "rhhhhhhhhhr" + /* 3 */ ".h.......h." + /* 4 */ ".h.......h." + /* 5 */ ".h.......h." + /* 6 */ "uhhhhhhhhhu" + /* 7 */ "jjjjjjjjjjj" + /* 8 */ "..........." + /* 9 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm" + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "lllllllllll" + /* 3 */ "rhhhhhhhhhr" + /* 4 */ ".h.......h." + /* 5 */ "uhhhhhhhhhu" + /* 6 */ "jjjjjjjjjjj" + /* 7 */ "..........." + /* 8 */ "..........." + /* 9 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm" + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ "lllllllllll" + /* 4 */ "hhhhhhhhhhh" + /* 5 */ "jjjjjjjjjjj" + /* 6 */ "..........." + /* 7 */ "..........." + /* 8 */ "..........." + /* 9 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // PlainsVillage_99 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // RoofedWell + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Windmill: + // The data has been exported from the gallery Plains, area index 60, ID 111, created by Aloe_vera + { + // Size: + 9, 16, 13, // SizeX = 9, SizeY = 16, SizeZ = 13 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 8, 15, 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: 6\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 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".aaaaa..." + /* 5 */ ".aaaaab.." + /* 6 */ ".aaaaac.." + /* 7 */ ".aaaaad.." + /* 8 */ ".aaaaa..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 1 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".efffe..." + /* 5 */ ".f...f..." + /* 6 */ ".fgh.i..." + /* 7 */ ".f...f..." + /* 8 */ ".efffe..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 2 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".ejjje..." + /* 5 */ ".j...f..." + /* 6 */ ".j.k.l..." + /* 7 */ ".j...f..." + /* 8 */ ".ejjje..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 3 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".efffe..." + /* 5 */ ".f..nf..." + /* 6 */ ".f.k.f..." + /* 7 */ ".f..nf..k" + /* 8 */ ".efffe..o" + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 4 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".epppe..." + /* 5 */ ".q...q..." + /* 6 */ ".q.k.q..." + /* 7 */ ".q...q..k" + /* 8 */ ".epppe..o" + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 5 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".efffe..." + /* 5 */ ".f...f..." + /* 6 */ ".f.k.f..k" + /* 7 */ ".f...f..o" + /* 8 */ ".efffe..o" + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 6 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".ejjje..." + /* 5 */ ".j...j..." + /* 6 */ ".j.k.j..k" + /* 7 */ ".j...j..o" + /* 8 */ ".ejjje..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 7 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.o" + /* 1 */ "mmmmmmm.o" + /* 2 */ "mmmmmmm.o" + /* 3 */ "........." + /* 4 */ ".efffe..." + /* 5 */ ".f...f..k" + /* 6 */ ".f.k.f..o" + /* 7 */ ".f...f..o" + /* 8 */ ".efffe..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 8 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.k" + /* 1 */ "mmmmmmm.k" + /* 2 */ "mmmmmmm.o" + /* 3 */ "........o" + /* 4 */ ".epppe..o" + /* 5 */ ".q...q..k" + /* 6 */ ".q.k.q..o" + /* 7 */ ".q...q..k" + /* 8 */ ".epppe..k" + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 9 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.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 */ "mmmmmmm.k" + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 10 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "mmmmmmm.." + /* 4 */ "rrrrrrr.k" + /* 5 */ "sfffffs.k" + /* 6 */ ".f...f..o" + /* 7 */ "tffffft.k" + /* 8 */ "uuuuuuu.o" + /* 9 */ "mmmmmmm.o" + /* 10 */ "mmmmmmm.o" + /* 11 */ "mmmmmmm.k" + /* 12 */ "mmmmmmm.k" + + // Level 11 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "mmmmmmm.." + /* 4 */ "mmmmmmm.." + /* 5 */ "rrrrrrr.o" + /* 6 */ "fffffff.o" + /* 7 */ "uuuuuuu.k" + /* 8 */ "mmmmmmm.." + /* 9 */ "mmmmmmm.." + /* 10 */ "mmmmmmm.o" + /* 11 */ "mmmmmmm.o" + /* 12 */ "mmmmmmm.o" + + // Level 12 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." + /* 3 */ "........." + /* 4 */ "........." + /* 5 */ "........o" + /* 6 */ "........k" + /* 7 */ "........." + /* 8 */ "........." + /* 9 */ "........." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." + + // Level 13 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." + /* 3 */ "........." + /* 4 */ "........o" + /* 5 */ "........o" + /* 6 */ "........k" + /* 7 */ "........." + /* 8 */ "........." + /* 9 */ "........." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." + + // Level 14 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." + /* 3 */ "........." + /* 4 */ "........o" + /* 5 */ "........k" + /* 6 */ "........." + /* 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 */ ".........", + + // Connectors: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // Windmill +}; // g_PlainsVillagePrefabs + + + + + + +const cPrefab::sDef g_PlainsVillageStartingPrefabs[] = +{ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Well: + // 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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // Well +}; + + + + + +// 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/SandVillagePrefabs.cpp b/src/Generating/Prefabs/SandVillagePrefabs.cpp new file mode 100644 index 000000000..23af0f0a6 --- /dev/null +++ b/src/Generating/Prefabs/SandVillagePrefabs.cpp @@ -0,0 +1,1887 @@ + +// 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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 5\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 5\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 5\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 5\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 5\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 5\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 5\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 5\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 1\n" /* wooddoorblock */ + "f:102: 0\n" /* glasspane */ + "g: 64: 8\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // House9x9 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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: 5\n" /* wooddoorblock */ + "g:102: 0\n" /* glasspane */ + "h: 64:12\n" /* wooddoorblock */ + "i:128: 7\n" /* sandstonestairs */ + "j: 50: 3\n" /* torch */ + "k: 50: 4\n" /* torch */ + "l:128: 6\n" /* sandstonestairs */ + "m: 19: 0\n" /* sponge */ + "n:128: 5\n" /* sandstonestairs */ + "o:128: 4\n" /* sandstonestairs */ + "p: 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 */ ".ddddfddd...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 */ ".dggdggdhdggd." + /* 2 */ ".g..........g." + /* 3 */ ".g..........g." + /* 4 */ ".g..........d." + /* 5 */ ".dggdhdgg...g." + /* 6 */ "........g...g." + /* 7 */ "mmmmmmm.d...d." + /* 8 */ "mmmmmmm.g...g." + /* 9 */ "mmmmmmm.g...g." + /* 10 */ "mmmmmmm.dgggd." + /* 11 */ "mmmmmmm......." + + // Level 3 + /* z\x* 1111 */ + /* * 01234567890123 */ + /* 0 */ "bbbbbbbbbbbbbb" + /* 1 */ "iddddddddddddc" + /* 2 */ ".d.....j.j..dc" + /* 3 */ ".d..........dc" + /* 4 */ ".d..k.k.....dc" + /* 5 */ "ldddddddd...dc" + /* 6 */ "eeeeeeead...dc" + /* 7 */ "mmmmmmmad...dc" + /* 8 */ "mmmmmmmad...dc" + /* 9 */ "mmmmmmmad...dc" + /* 10 */ "mmmmmmmadddddc" + /* 11 */ "mmmmmmman...oc" + + // Level 4 + /* z\x* 1111 */ + /* * 01234567890123 */ + /* 0 */ ".............." + /* 1 */ "bbbbbbbbbbbbb." + /* 2 */ "idddddddddddc." + /* 3 */ ".dp........dc." + /* 4 */ "lddddddddd.dc." + /* 5 */ "eeeeeeeead.dc." + /* 6 */ "........ad.dc." + /* 7 */ "mmmmmmm.ad.dc." + /* 8 */ "mmmmmmm.ad.dc." + /* 9 */ "mmmmmmm.adkdc." + /* 10 */ "mmmmmmm.adddc." + /* 11 */ "mmmmmmm.an.oc." + + // 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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // HouseL14x12 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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: 5\n" /* wooddoorblock */ + "g: 64: 7\n" /* wooddoorblock */ + "h:102: 0\n" /* glasspane */ + "i: 64:12\n" /* wooddoorblock */ + "j:128: 7\n" /* sandstonestairs */ + "k: 50: 3\n" /* torch */ + "l: 50: 2\n" /* torch */ + "m: 19: 0\n" /* sponge */ + "n: 50: 4\n" /* torch */ + "o:128: 6\n" /* sandstonestairs */ + "p: 50: 1\n" /* torch */ + "q:128: 5\n" /* sandstonestairs */ + "r:128: 4\n" /* sandstonestairs */, + + // Block data: + // Level 0 + /* z\x* 1111 */ + /* * 01234567890123 */ + /* 0 */ "....abc......." + /* 1 */ ".dddddddddddd." + /* 2 */ ".dddddddddddd." + /* 3 */ ".dddddddddddd." + /* 4 */ ".dddddddddddd." + /* 5 */ ".dddddddddddd." + /* 6 */ ".dddddddddddd." + /* 7 */ ".dddddddddddd." + /* 8 */ "....aeddddddd." + /* 9 */ "mmmmm.ddddddd." + /* 10 */ "mmmmm.ddddddd." + /* 11 */ "mmmmm........." + + // 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 */ ".ddddgd.....d." + /* 8 */ "......d.....d." + /* 9 */ "mmmmm.d.....d." + /* 10 */ "mmmmm.ddddddd." + /* 11 */ "mmmmm........." + + // Level 2 + /* z\x* 1111 */ + /* * 01234567890123 */ + /* 0 */ ".............." + /* 1 */ ".dhhdidhhdhhd." + /* 2 */ ".h..........h." + /* 3 */ ".h..........h." + /* 4 */ ".d..........d." + /* 5 */ ".h..........h." + /* 6 */ ".h..........h." + /* 7 */ ".dhhdid.....d." + /* 8 */ "......h.....h." + /* 9 */ "mmmmm.h.....h." + /* 10 */ "mmmmm.dhhdhhd." + /* 11 */ "mmmmm........." + + // Level 3 + /* z\x* 1111 */ + /* * 01234567890123 */ + /* 0 */ "bbbbbbbbbbbbbb" + /* 1 */ "jddddddddddddc" + /* 2 */ ".d..k.k.....dc" + /* 3 */ ".d..........dc" + /* 4 */ ".d.........ldc" + /* 5 */ ".d..........dc" + /* 6 */ ".d..n.n.....dc" + /* 7 */ "oddddddp...ldc" + /* 8 */ "eeeeead.....dc" + /* 9 */ "mmmmmad.....dc" + /* 10 */ "mmmmmadddddddc" + /* 11 */ "mmmmmaq.....rc" + + // Level 4 + /* z\x* 1111 */ + /* * 01234567890123 */ + /* 0 */ ".............." + /* 1 */ "bbbbbbbbbbbbc." + /* 2 */ "jdddddddddddc." + /* 3 */ ".d.........dc." + /* 4 */ ".d.........dc." + /* 5 */ ".d.........dc." + /* 6 */ "oddddddd...dc." + /* 7 */ "eeeeeead...dc." + /* 8 */ "......ad...dc." + /* 9 */ "mmmmm.ad...dc." + /* 10 */ "mmmmm.adddddc." + /* 11 */ "mmmmm.aq...rc." + + // Level 5 + /* z\x* 1111 */ + /* * 01234567890123 */ + /* 0 */ ".............." + /* 1 */ ".............." + /* 2 */ "bbbbbbbbbbbb.." + /* 3 */ "jddddddddddc.." + /* 4 */ ".d........dc.." + /* 5 */ "odddddddd.dc.." + /* 6 */ "eeeeeeeed.dc.." + /* 7 */ ".......ad.dc.." + /* 8 */ ".......ad.dc.." + /* 9 */ "mmmmm..ad.dc.." + /* 10 */ "mmmmm..adddc.." + /* 11 */ "mmmmm..aq.rc.." + + // 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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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: 3\n" /* wooddoorblock */ + "h: 64: 8\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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // SmallHut +}; // g_SandVillagePrefabs + + + + + + +const cPrefab::sDef g_SandVillageStartingPrefabs[] = +{ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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: + "", + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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/VillageGen.cpp b/src/Generating/VillageGen.cpp new file mode 100644 index 000000000..fb6191df2 --- /dev/null +++ b/src/Generating/VillageGen.cpp @@ -0,0 +1,116 @@ + +// VillageGen.cpp + +// Implements the cVillageGen class representing the village generator + +#include "Globals.h" +#include "VillageGen.h" +#include "Prefabs/PlainsVillagePrefabs.h" +#include "Prefabs/SandVillagePrefabs.h" + + + + + +class cVillageGen::cVillage : + public cGridStructGen::cStructure +{ + typedef cGridStructGen::cStructure super; + +public: + cVillage(int a_Seed, int a_OriginX, int a_OriginZ, cPrefabPiecePool & a_Prefabs) : + super(a_OriginX, a_OriginZ), + m_Seed(a_Seed), + m_Prefabs(a_Prefabs) + { + } + +protected: + /** Seed for the random functions */ + int m_Seed; + + /** Prefabs to use for buildings */ + cPrefabPiecePool & m_Prefabs; + + // cGrdStructGen::cStructure overrides: + virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override + { + // TODO + } +} ; + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cVillageGen: + +cPrefabPiecePool cVillageGen::m_SandVillage (g_SandVillagePrefabs, g_SandVillagePrefabsCount, g_SandVillageStartingPrefabs, g_SandVillageStartingPrefabsCount); +cPrefabPiecePool cVillageGen::m_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVillagePrefabsCount, g_PlainsVillageStartingPrefabs, g_PlainsVillageStartingPrefabsCount); + + + + + +cVillageGen::cVillageGen(int a_Seed, int a_GridSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) : + super(a_Seed, a_GridSize, a_GridSize, 128, 128, 100), + m_BiomeGen(a_BiomeGen), + m_HeightGen(a_HeightGen) +{ +} + + + + + +cGridStructGen::cStructurePtr cVillageGen::CreateStructure(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 + cPrefabPiecePool * VillagePrefabs = NULL; + for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++) + { + switch (Biomes[i]) + { + case biDesert: + case biDesertM: + { + // These biomes allow sand villages + VillagePrefabs = &m_SandVillage; + break; + } + case biPlains: + case biSavanna: + case biSavannaM: + case biSunflowerPlains: + { + // These biomes allow plains-style villages + VillagePrefabs = &m_PlainsVillage; + break; + } + default: + { + // Village-unfriendly biome, bail out with zero structure: + return cStructurePtr(); + } + } // switch (Biomes[i]) + } // for i - Biomes[] + + // Create a village based on the chosen prefabs: + if (VillagePrefabs == NULL) + { + return cStructurePtr(); + } + return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, *VillagePrefabs)); +} + + + + diff --git a/src/Generating/VillageGen.h b/src/Generating/VillageGen.h new file mode 100644 index 000000000..d3cc8ef9c --- /dev/null +++ b/src/Generating/VillageGen.h @@ -0,0 +1,48 @@ + +// 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, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen); + +protected: + class cVillage; // fwd: VillageGen.cpp + + /** The prefabs for the sand village. We're not exactly using the cPiecePool functionality, only the containment. */ + static cPrefabPiecePool m_SandVillage; + + /** The prefabs for the plains village. We're not exactly using the cPiecePool functionality, only the containment. */ + static cPrefabPiecePool m_PlainsVillage; + + /** 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_OriginX, int a_OriginZ) override; +} ; + + + + From 9c8e8ef7aece2f881ef97c387600c8a751579b20 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 12 May 2014 22:43:59 +0200 Subject: [PATCH 049/312] VillageGen: Added well placement and the general algorithm description. --- src/Generating/Prefab.h | 3 + src/Generating/VillageGen.cpp | 147 ++++++++++++++++++++++++++++++++-- src/Generating/VillageGen.h | 8 +- 3 files changed, 152 insertions(+), 6 deletions(-) diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index 37db2ff16..472584c3a 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -95,6 +95,9 @@ public: /** 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; + + /** Returns the unmodified DefaultWeight property for the piece. */ + int GetDefaultWeight(void) const { return m_DefaultWeight; } protected: /** Packs complete definition of a single block, for per-letter assignment. */ diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index fb6191df2..3d89d7aa2 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -12,30 +12,167 @@ +/* +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 starting by its well. The well is placed in the grid's origin point. Then a set of +random lengths roads is generated - 4 roads going from the well, then at the end of each road another set of +roads, crossing them perpendicular, then at the end of those another set, up to a set maximum branching +depth. The roads are placed in a T or L shape, with the old road being the center stem of the T. Roads avoid +crossing each other and going further away from the well than the maximum block size of the village. +Finally, houses are places along the roads, avoiding collisions with already-existing items. + +When the village is about to be drawn into a chunk, it queries the heights for each item intersecting the +chunk. The prefabs 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. +*/ + class cVillageGen::cVillage : public cGridStructGen::cStructure { typedef cGridStructGen::cStructure super; public: - cVillage(int a_Seed, int a_OriginX, int a_OriginZ, cPrefabPiecePool & a_Prefabs) : + cVillage( + int a_Seed, + int a_OriginX, int a_OriginZ, + int a_MaxRoadDepth, + int a_MaxSize, + cPrefabPiecePool & a_Prefabs, + cTerrainHeightGen & a_HeightGen + ) : super(a_OriginX, a_OriginZ), m_Seed(a_Seed), - m_Prefabs(a_Prefabs) + 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), + m_Prefabs(a_Prefabs), + m_HeightGen(a_HeightGen) { + PlaceWell(); + BuildRoads(a_MaxRoadDepth); + PlaceHouses(); } protected: + class cItem + { + public: + /* The position of the item, X/Z-wise: */ + int m_MinX, m_MaxX, m_MinZ, m_MaxZ; + + /** The prefab to use. If NULL, this is a road. */ + cPrefab * m_Prefab; + + /** Number of rotations that should be applied to the prefab. */ + int m_NumRotations; + + /* The bottom of the prefab. Only valid if the item is a prefab, not valid for roads. */ + int m_BaseY; + + /** Creates a new item with the specified parameters. + m_BaseY is set to -1 and will be adjusted later on when drawing. */ + cItem(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, cPrefab * a_Prefab, int a_NumRotations) : + m_MinX(a_MinX), + m_MaxX(a_MaxX), + m_MinZ(a_MinZ), + m_MaxZ(a_MaxZ), + m_Prefab(a_Prefab), + m_NumRotations(a_NumRotations), + m_BaseY(-1) + { + } + } ; + typedef SharedPtr cItemPtr; + typedef std::vector cItemPtrs; + + /** 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; + /** Prefabs to use for buildings */ cPrefabPiecePool & m_Prefabs; + /** The underlying height generator, used for placing the structures on top of the terrain. */ + cTerrainHeightGen & m_HeightGen; + + /** The items that are generated in the village (houses, roads). */ + cItemPtrs m_Items; + + + /** Places the well at the center of the village */ + void PlaceWell(void) + { + // Pick a prefab from the starting pieces: + cPieces StartingPieces = ((cPiecePool &)m_Prefabs).GetStartingPieces(); + ASSERT(!StartingPieces.empty()); + int TotalWeight = 0; + for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr) + { + TotalWeight += ((const cPrefab *)(*itr))->GetDefaultWeight(); + } + ASSERT(TotalWeight > 0); + int rnd = (m_Noise.IntNoise2DInt(m_OriginX, m_OriginZ) / 7) % TotalWeight; + cPiece * WellPiece = StartingPieces[0]; + for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr) + { + rnd -= ((const cPrefab *)(*itr))->GetDefaultWeight(); + if (rnd <= 0) + { + WellPiece = *itr; + break; + } + } + ASSERT(WellPiece != NULL); + + // Pick a rotation: + // TODO + int NumRotations = 0; + Vector3i Size = WellPiece->GetSize(); + + // Put the well in the placed items array: + m_Items.push_back(cItemPtr(new cItem(m_OriginX, m_OriginX + Size.x, m_OriginZ, m_OriginZ + Size.z, (cPrefab *)WellPiece, NumRotations))); + } + + + /** Places the roads going from the well outwards. */ + void BuildRoads(int a_MaxRoadDepth) + { + /* + ASSERT(m_Items.size() == 1); + const cItem & Well = *m_Items[0]; + */ + // TODO + } + + + /** Places houses along the roads. */ + void PlaceHouses(void) + { + // TODO + } + + // cGrdStructGen::cStructure overrides: virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override { // TODO + // Iterate over all items + // Each intersecting prefab is placed on ground (if not already placed), then drawn + // Each intersecting road is drawn by replacing top soil blocks with gravel / sandstone blocks } } ; @@ -53,8 +190,8 @@ cPrefabPiecePool cVillageGen::m_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVi -cVillageGen::cVillageGen(int a_Seed, int a_GridSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) : - super(a_Seed, a_GridSize, a_GridSize, 128, 128, 100), +cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxRoadDepth, int a_MaxSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) : + super(a_Seed, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 100), m_BiomeGen(a_BiomeGen), m_HeightGen(a_HeightGen) { @@ -108,7 +245,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ { return cStructurePtr(); } - return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, *VillagePrefabs)); + return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxRoadDepth, m_MaxSize, *VillagePrefabs, m_HeightGen)); } diff --git a/src/Generating/VillageGen.h b/src/Generating/VillageGen.h index d3cc8ef9c..acbd76881 100644 --- a/src/Generating/VillageGen.h +++ b/src/Generating/VillageGen.h @@ -21,7 +21,7 @@ class cVillageGen : { typedef cGridStructGen super; public: - cVillageGen(int a_Seed, int a_GridSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen); + cVillageGen(int a_Seed, int a_GridSize, int a_MaxRoadDepth, int a_MaxSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen); protected: class cVillage; // fwd: VillageGen.cpp @@ -31,6 +31,12 @@ protected: /** The prefabs for the plains village. We're not exactly using the cPiecePool functionality, only the containment. */ static cPrefabPiecePool m_PlainsVillage; + + /** Maximum number of roads generated one from another (tree depth). */ + int m_MaxRoadDepth; + + /** Maximum size, in X/Z blocks, of the village (radius from the origin) */ + int m_MaxSize; /** The underlying biome generator that defines whether the village is created or not */ cBiomeGen & m_BiomeGen; From 3660ce68343ad2e867e49d1650f61fc0eb85ac23 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 May 2014 00:12:01 +0200 Subject: [PATCH 050/312] cPrefab can be constructed in code. --- src/Generating/Prefab.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/Generating/Prefab.h | 15 +++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 0f20603be..9aef7a94b 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -136,6 +136,33 @@ 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_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) { @@ -257,6 +284,15 @@ int cPrefab::GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cC +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 472584c3a..c08413e87 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -84,8 +84,13 @@ public: int m_AddWeightIfSame; }; + + /** 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; @@ -98,6 +103,12 @@ public: /** 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); protected: /** Packs complete definition of a single block, for per-letter assignment. */ @@ -160,6 +171,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); From f5fdbdaf29738f51fdb8a4a0e5aa78631c6540cf Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 May 2014 00:14:06 +0200 Subject: [PATCH 051/312] VillageGen rewritten using BFSPieceGenerator. Piece composition is not good yet, the buildings aren't height-adjusted and the road pieces will need special processing. This is mainly for adjusting the per-piece params. --- src/Generating/ComposableGenerator.cpp | 9 + .../Prefabs/PlainsVillagePrefabs.cpp | 416 +++++++++--------- src/Generating/Prefabs/SandVillagePrefabs.cpp | 185 ++++---- src/Generating/VillageGen.cpp | 196 ++++----- src/Generating/VillageGen.h | 12 +- 5 files changed, 406 insertions(+), 412 deletions(-) diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 2e886336f..1bb836684 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -25,6 +25,7 @@ #include "Noise3DGenerator.h" #include "POCPieceGenerator.h" #include "Ravines.h" +#include "VillageGen.h" @@ -32,6 +33,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cTerrainCompositionGen: + cTerrainCompositionGen * cTerrainCompositionGen::CreateCompositionGen(cIniFile & a_IniFile, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen, int a_Seed) { AString CompoGenName = a_IniFile.GetValueSet("Generator", "CompositionGen", ""); @@ -404,6 +406,13 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) { m_FinishGens.push_back(new cStructGenTrees(Seed, m_BiomeGen, m_HeightGen, m_CompositionGen)); } + else if (NoCaseCompare(*itr, "Villages") == 0) + { + int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 256); + int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 7); + int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); + m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxDepth, MaxSize, *m_BiomeGen, *m_HeightGen)); + } else if (NoCaseCompare(*itr, "WaterLakes") == 0) { int Probability = a_IniFile.GetValueSetI("Generator", "WaterLakesProbability", 25); diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp index f59e22fb3..508f0d3b6 100644 --- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -174,7 +174,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 10 */ ".......mmmmm", // Connectors: - "", + "-1: 7, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -216,7 +216,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "d: 4: 0\n" /* cobblestone */ "e: 17: 0\n" /* tree */ "f: 5: 0\n" /* wood */ - "g: 64: 5\n" /* wooddoorblock */ + "g: 64: 7\n" /* wooddoorblock */ "h: 64:12\n" /* wooddoorblock */ "i:102: 0\n" /* glasspane */ "j: 53: 2\n" /* woodstairs */ @@ -288,7 +288,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ ".......", // Connectors: - "", + "-1: 3, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -330,7 +330,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "d: 4: 0\n" /* cobblestone */ "e: 17: 0\n" /* tree */ "f: 5: 0\n" /* wood */ - "g: 64: 5\n" /* wooddoorblock */ + "g: 64: 7\n" /* wooddoorblock */ "h:102: 0\n" /* glasspane */ "i: 64:12\n" /* wooddoorblock */ "j: 53: 2\n" /* woodstairs */ @@ -434,7 +434,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 8 */ "...........", // Connectors: - "", + "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -561,7 +561,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 8 */ "..lgp..", // Connectors: - "", + "-1: 3, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -725,7 +725,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 8 */ "...............", // Connectors: - "", + "-1: 7, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1016,7 +1016,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 12 */ ".......", // Connectors: - "", + "-1: 3, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1087,7 +1087,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 8 */ "dmmmmmdmdmmmmmd", // Connectors: - "", + "-1: 7, 0, 8: 3\n" /* Type -1, direction Z+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1134,7 +1134,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "i: 53: 1\n" /* woodstairs */ "j: 85: 0\n" /* fence */ "k: 53: 0\n" /* woodstairs */ - "l: 64: 4\n" /* wooddoorblock */ + "l: 64: 6\n" /* wooddoorblock */ "m: 19: 0\n" /* sponge */ "n: 64: 0\n" /* wooddoorblock */ "o:102: 0\n" /* glasspane */ @@ -1238,7 +1238,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 10 */ "mmkbimmmmm", // Connectors: - "", + "-1: 1, 0, 5: 4\n" /* Type -1, direction X- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1281,22 +1281,23 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "e: 5: 0\n" /* wood */ "f: 67: 3\n" /* stairs */ "g: 17: 0\n" /* tree */ - "h: 64: 5\n" /* wooddoorblock */ - "i:102: 0\n" /* glasspane */ - "j: 64:12\n" /* wooddoorblock */ - "k: 53: 2\n" /* woodstairs */ - "l: 53: 1\n" /* woodstairs */ + "h: 64: 7\n" /* wooddoorblock */ + "i: 64: 5\n" /* wooddoorblock */ + "j:102: 0\n" /* glasspane */ + "k: 64:12\n" /* wooddoorblock */ + "l: 53: 2\n" /* woodstairs */ "m: 19: 0\n" /* sponge */ - "n: 53: 7\n" /* woodstairs */ - "o: 53: 6\n" /* woodstairs */ - "p: 53: 3\n" /* woodstairs */ - "q: 53: 0\n" /* woodstairs */ - "r: 53: 5\n" /* woodstairs */ - "s: 53: 4\n" /* woodstairs */ - "t: 50: 3\n" /* torch */ - "u: 50: 2\n" /* torch */ - "v: 50: 4\n" /* torch */ - "w: 50: 1\n" /* torch */, + "n: 53: 1\n" /* woodstairs */ + "o: 53: 7\n" /* woodstairs */ + "p: 53: 6\n" /* woodstairs */ + "q: 53: 3\n" /* woodstairs */ + "r: 53: 0\n" /* woodstairs */ + "s: 53: 5\n" /* woodstairs */ + "t: 53: 4\n" /* woodstairs */ + "u: 50: 3\n" /* torch */ + "v: 50: 2\n" /* torch */ + "w: 50: 4\n" /* torch */ + "x: 50: 1\n" /* torch */, // Block data: // Level 0 @@ -1329,7 +1330,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 4 */ ".e............e." /* 5 */ ".e............e." /* 6 */ ".e............e." - /* 7 */ ".geeeeheg.....e." + /* 7 */ ".geeeeieg.....e." /* 8 */ "mmmmmm.me.....e." /* 9 */ "mmmmmmmme.....e." /* 10 */ "mmmmmmmme.....e." @@ -1343,81 +1344,81 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* z\x* 111111 */ /* * 0123456789012345 */ /* 0 */ "................" - /* 1 */ ".geiieiigjgiieg." - /* 2 */ ".i............e." - /* 3 */ ".i............i." - /* 4 */ ".i............i." - /* 5 */ ".i............e." - /* 6 */ ".i............i." - /* 7 */ ".geiiejeg.....i." + /* 1 */ ".gejjejjgkgjjeg." + /* 2 */ ".j............e." + /* 3 */ ".j............j." + /* 4 */ ".j............j." + /* 5 */ ".j............e." + /* 6 */ ".j............j." + /* 7 */ ".gejjekeg.....j." /* 8 */ "mmmmmm.me.....e." - /* 9 */ "mmmmmmmmi.....i." - /* 10 */ "mmmmmmmmi.....i." + /* 9 */ "mmmmmmmmj.....j." + /* 10 */ "mmmmmmmmj.....j." /* 11 */ "mmmmmmmme.....e." - /* 12 */ "mmmmmmmmi.....i." - /* 13 */ "mmmmmmmmi.....i." - /* 14 */ "mmmmmmmmgiiiiig." + /* 12 */ "mmmmmmmmj.....j." + /* 13 */ "mmmmmmmmj.....j." + /* 14 */ "mmmmmmmmgjjjjjg." /* 15 */ "mmmmmmmm........" // Level 3 /* z\x* 111111 */ /* * 0123456789012345 */ - /* 0 */ "kkkkkkkkkkkkkkkl" - /* 1 */ "ngeeeeeegegeeegl" - /* 2 */ ".e............el" - /* 3 */ ".e............el" - /* 4 */ ".e............el" - /* 5 */ ".e............el" - /* 6 */ ".e............el" - /* 7 */ "ogeeeeeeg.....el" - /* 8 */ "pppppppqe.....el" - /* 9 */ "mmmmmmmqe.....el" - /* 10 */ "mmmmmmmqe.....el" - /* 11 */ "mmmmmmmqe.....el" - /* 12 */ "mmmmmmmqe.....el" - /* 13 */ "mmmmmmmqe.....el" - /* 14 */ "mmmmmmmqgeeeeegl" - /* 15 */ "mmmmmmmqr.....sl" + /* 0 */ "llllllllllllllln" + /* 1 */ "ogeeeeeegegeeegn" + /* 2 */ ".e............en" + /* 3 */ ".e............en" + /* 4 */ ".e............en" + /* 5 */ ".e............en" + /* 6 */ ".e............en" + /* 7 */ "pgeeeeeeg.....en" + /* 8 */ "qqqqqqqre.....en" + /* 9 */ "mmmmmmmre.....en" + /* 10 */ "mmmmmmmre.....en" + /* 11 */ "mmmmmmmre.....en" + /* 12 */ "mmmmmmmre.....en" + /* 13 */ "mmmmmmmre.....en" + /* 14 */ "mmmmmmmrgeeeeegn" + /* 15 */ "mmmmmmmrs.....tn" // Level 4 /* z\x* 111111 */ /* * 0123456789012345 */ /* 0 */ "................" - /* 1 */ "kkkkkkkkkkkkkkk." - /* 2 */ "neeeeeeeeeeeeel." - /* 3 */ ".e.........t.el." - /* 4 */ ".e..........uel." - /* 5 */ ".e......v....el." - /* 6 */ "oeeeeeeeee...el." - /* 7 */ "ppppppppqew..el." - /* 8 */ "mmmmmmmmqe...el." - /* 9 */ "mmmmmmmmqe...el." - /* 10 */ "mmmmmmmmqe...el." - /* 11 */ "mmmmmmmmqe...el." - /* 12 */ "mmmmmmmmqe...el." - /* 13 */ "mmmmmmmmqe...el." - /* 14 */ "mmmmmmmmqeeeeel." - /* 15 */ "mmmmmmmmqr...sl." + /* 1 */ "lllllllllllllll." + /* 2 */ "oeeeeeeeeeeeeen." + /* 3 */ ".e.........u.en." + /* 4 */ ".e..........ven." + /* 5 */ ".e......w....en." + /* 6 */ "peeeeeeeee...en." + /* 7 */ "qqqqqqqqrex..en." + /* 8 */ "mmmmmmmmre...en." + /* 9 */ "mmmmmmmmre...en." + /* 10 */ "mmmmmmmmre...en." + /* 11 */ "mmmmmmmmre...en." + /* 12 */ "mmmmmmmmre...en." + /* 13 */ "mmmmmmmmre...en." + /* 14 */ "mmmmmmmmreeeeen." + /* 15 */ "mmmmmmmmrs...tn." // Level 5 /* z\x* 111111 */ /* * 0123456789012345 */ /* 0 */ "................" /* 1 */ "................" - /* 2 */ "kkkkkkkkkkkkkl.." - /* 3 */ "neeeeeeeeeeeel.." - /* 4 */ ".ew.........el.." - /* 5 */ "oeeeeeeeeee.el.." - /* 6 */ "pppppppppqe.el.." - /* 7 */ ".........qe.el.." - /* 8 */ "mmmmmmmm.qe.el.." - /* 9 */ "mmmmmmmm.qe.el.." - /* 10 */ "mmmmmmmm.qe.el.." - /* 11 */ "mmmmmmmm.qe.el.." - /* 12 */ "mmmmmmmm.qe.el.." - /* 13 */ "mmmmmmmm.qevel.." - /* 14 */ "mmmmmmmm.qeeel.." - /* 15 */ "mmmmmmmm.qr.sl.." + /* 2 */ "llllllllllllln.." + /* 3 */ "oeeeeeeeeeeeen.." + /* 4 */ ".ex.........en.." + /* 5 */ "peeeeeeeeee.en.." + /* 6 */ "qqqqqqqqqre.en.." + /* 7 */ ".........re.en.." + /* 8 */ "mmmmmmmm.re.en.." + /* 9 */ "mmmmmmmm.re.en.." + /* 10 */ "mmmmmmmm.re.en.." + /* 11 */ "mmmmmmmm.re.en.." + /* 12 */ "mmmmmmmm.re.en.." + /* 13 */ "mmmmmmmm.rewen.." + /* 14 */ "mmmmmmmm.reeen.." + /* 15 */ "mmmmmmmm.rs.tn.." // Level 6 /* z\x* 111111 */ @@ -1425,22 +1426,22 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 0 */ "................" /* 1 */ "................" /* 2 */ "................" - /* 3 */ "kkkkkkkkkkkkk..." - /* 4 */ "eeeeeeeeeeeel..." - /* 5 */ "ppppppppppqel..." - /* 6 */ "mmmmmmmmmmqel..." - /* 7 */ "mmmmmmmmmmqel..." - /* 8 */ "mmmmmmmmmmqel..." - /* 9 */ "mmmmmmmmmmqel..." - /* 10 */ "mmmmmmmmmmqel..." - /* 11 */ "mmmmmmmmmmqel..." - /* 12 */ "mmmmmmmmmmqel..." - /* 13 */ "mmmmmmmmmmqel..." - /* 14 */ "mmmmmmmmmmqel..." - /* 15 */ "mmmmmmmmmmqel...", + /* 3 */ "lllllllllllll..." + /* 4 */ "eeeeeeeeeeeen..." + /* 5 */ "qqqqqqqqqqren..." + /* 6 */ "mmmmmmmmmmren..." + /* 7 */ "mmmmmmmmmmren..." + /* 8 */ "mmmmmmmmmmren..." + /* 9 */ "mmmmmmmmmmren..." + /* 10 */ "mmmmmmmmmmren..." + /* 11 */ "mmmmmmmmmmren..." + /* 12 */ "mmmmmmmmmmren..." + /* 13 */ "mmmmmmmmmmren..." + /* 14 */ "mmmmmmmmmmren..." + /* 15 */ "mmmmmmmmmmren...", // Connectors: - "", + "-1: 9, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1506,7 +1507,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ "..........", // Connectors: - "", + "-1: 9, 0, 3: 5\n" /* Type -1, direction X+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1548,7 +1549,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "d: 67: 2\n" /* stairs */ "e: 67: 1\n" /* stairs */ "f: 4: 0\n" /* cobblestone */ - "g: 64: 1\n" /* wooddoorblock */ + "g: 64: 7\n" /* wooddoorblock */ "h: 53: 3\n" /* woodstairs */ "i: 53: 1\n" /* woodstairs */ "j: 85: 0\n" /* fence */ @@ -1556,7 +1557,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "l: 53: 2\n" /* woodstairs */ "m: 19: 0\n" /* sponge */ "n:102: 0\n" /* glasspane */ - "o: 64: 8\n" /* wooddoorblock */ + "o: 64:12\n" /* wooddoorblock */ "p: 50: 3\n" /* torch */ "q: 72: 0\n" /* woodplate */ "r: 50: 4\n" /* torch */ @@ -1646,7 +1647,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ "............", // Connectors: - "", + "-1: 8, 1, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1689,19 +1690,18 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "e: 67: 3\n" /* stairs */ "f: 17: 0\n" /* tree */ "g: 5: 0\n" /* wood */ - "h: 64: 5\n" /* wooddoorblock */ - "i: 64: 7\n" /* wooddoorblock */ - "j:102: 0\n" /* glasspane */ - "k: 64:12\n" /* wooddoorblock */ - "l: 53: 2\n" /* woodstairs */ + "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: 53: 7\n" /* woodstairs */ - "o: 17: 4\n" /* tree */ - "p: 17: 8\n" /* tree */ - "q: 50: 3\n" /* torch */ - "r: 50: 4\n" /* torch */ - "s: 53: 6\n" /* woodstairs */ - "t: 53: 3\n" /* woodstairs */, + "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 @@ -1727,46 +1727,46 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 4 */ ".f.......f." /* 5 */ ".g.......g." /* 6 */ ".g.......g." - /* 7 */ ".fggfifggf." + /* 7 */ ".fggfhfggf." /* 8 */ "..........." // Level 2 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ ".fjjfkfjjf." - /* 2 */ ".j.......j." - /* 3 */ ".j.......j." + /* 1 */ ".fiifjfiif." + /* 2 */ ".i.......i." + /* 3 */ ".i.......i." /* 4 */ ".f.......f." - /* 5 */ ".j.......j." - /* 6 */ ".j.......j." - /* 7 */ ".fjjfkfjjf." + /* 5 */ ".i.......i." + /* 6 */ ".i.......i." + /* 7 */ ".fiifjfiif." /* 8 */ "..........." // Level 3 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "lllllllllll" - /* 1 */ "nfooooooofn" - /* 2 */ ".p..q.q..p." - /* 3 */ ".p.......p." - /* 4 */ ".p.......p." - /* 5 */ ".p.......p." - /* 6 */ ".p..r.r..p." - /* 7 */ "sfooooooofs" - /* 8 */ "ttttttttttt" + /* 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 4 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ "lllllllllll" - /* 2 */ "ngggggggggn" + /* 1 */ "kkkkkkkkkkk" + /* 2 */ "lgggggggggl" /* 3 */ ".g.......g." /* 4 */ ".g.......g." /* 5 */ ".g.......g." - /* 6 */ "sgggggggggs" - /* 7 */ "ttttttttttt" + /* 6 */ "rgggggggggr" + /* 7 */ "sssssssssss" /* 8 */ "..........." // Level 5 @@ -1774,11 +1774,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* * 01234567890 */ /* 0 */ "..........." /* 1 */ "..........." - /* 2 */ "lllllllllll" - /* 3 */ "ngggggggggn" + /* 2 */ "kkkkkkkkkkk" + /* 3 */ "lgggggggggl" /* 4 */ ".g.......g." - /* 5 */ "sgggggggggs" - /* 6 */ "ttttttttttt" + /* 5 */ "rgggggggggr" + /* 6 */ "sssssssssss" /* 7 */ "..........." /* 8 */ "..........." @@ -1788,15 +1788,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 0 */ "..........." /* 1 */ "..........." /* 2 */ "..........." - /* 3 */ "lllllllllll" + /* 3 */ "kkkkkkkkkkk" /* 4 */ "ggggggggggg" - /* 5 */ "ttttttttttt" + /* 5 */ "sssssssssss" /* 6 */ "..........." /* 7 */ "..........." /* 8 */ "...........", // Connectors: - "", + "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2025,7 +2025,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 15 */ "mmmmmmmmmmmmmmm", // Connectors: - "", + "-1: 7, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2069,7 +2069,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "f: 4: 0\n" /* cobblestone */ "g: 17: 0\n" /* tree */ "h: 5: 0\n" /* wood */ - "i: 64: 5\n" /* wooddoorblock */ + "i: 64: 7\n" /* wooddoorblock */ "j:102: 0\n" /* glasspane */ "k: 64:12\n" /* wooddoorblock */ "l: 53: 2\n" /* woodstairs */ @@ -2151,7 +2151,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ ".........", // Connectors: - "", + "-1: 4, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2193,7 +2193,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "d: 4: 0\n" /* cobblestone */ "e: 17: 0\n" /* tree */ "f: 5: 0\n" /* wood */ - "g: 64: 5\n" /* wooddoorblock */ + "g: 64: 7\n" /* wooddoorblock */ "h:102: 0\n" /* glasspane */ "i: 64:12\n" /* wooddoorblock */ "j: 53: 2\n" /* woodstairs */ @@ -2271,7 +2271,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ "...........", // Connectors: - "", + "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2313,7 +2313,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "d: 4: 0\n" /* cobblestone */ "e: 17: 0\n" /* tree */ "f: 5: 0\n" /* wood */ - "g: 64: 5\n" /* wooddoorblock */ + "g: 64: 7\n" /* wooddoorblock */ "h:102: 0\n" /* glasspane */ "i: 64:12\n" /* wooddoorblock */ "j: 53: 2\n" /* woodstairs */ @@ -2422,7 +2422,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 10 */ "mmmm..tfl..", // Connectors: - "", + "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2464,7 +2464,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "d: 4: 0\n" /* cobblestone */ "e: 17: 0\n" /* tree */ "f: 5: 0\n" /* wood */ - "g: 64: 5\n" /* wooddoorblock */ + "g: 64: 7\n" /* wooddoorblock */ "h:102: 0\n" /* glasspane */ "i: 64:12\n" /* wooddoorblock */ "j: 53: 2\n" /* woodstairs */ @@ -2571,7 +2571,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 10 */ "..kfl.....kfl..", // Connectors: - "", + "-1: 7, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2613,7 +2613,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "d: 4: 0\n" /* cobblestone */ "e: 17: 0\n" /* tree */ "f: 5: 0\n" /* wood */ - "g: 64: 5\n" /* wooddoorblock */ + "g: 64: 7\n" /* wooddoorblock */ "h: 53: 3\n" /* woodstairs */ "i: 85: 0\n" /* fence */ "j: 53: 2\n" /* woodstairs */ @@ -2698,7 +2698,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ "...........", // Connectors: - "", + "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2740,15 +2740,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "d: 4: 0\n" /* cobblestone */ "e: 17: 0\n" /* tree */ "f: 5: 0\n" /* wood */ - "g: 64: 5\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 */ + "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:102: 0\n" /* glasspane */ - "o: 64:13\n" /* wooddoorblock */ + "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 */ @@ -2776,12 +2776,12 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* z\x* 11 */ /* * 012345678901 */ /* 0 */ "............" - /* 1 */ ".efffggfffe." + /* 1 */ ".efffghfffe." /* 2 */ ".f........f." - /* 3 */ ".fh......hf." - /* 4 */ ".fi......if." - /* 5 */ ".fj......jf." - /* 6 */ ".f.kilkil.f." + /* 3 */ ".fi......if." + /* 4 */ ".fj......jf." + /* 5 */ ".fk......kf." + /* 6 */ ".f.ljnljn.f." /* 7 */ ".effffffffe." /* 8 */ "............" @@ -2789,19 +2789,19 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* z\x* 11 */ /* * 012345678901 */ /* 0 */ "............" - /* 1 */ ".ennfopfnne." - /* 2 */ ".n..q..q..n." - /* 3 */ ".n........n." + /* 1 */ ".eoofppfooe." + /* 2 */ ".o..q..q..o." + /* 3 */ ".o........o." /* 4 */ ".fr......rf." - /* 5 */ ".n........n." - /* 6 */ ".n..r..r..n." - /* 7 */ ".ennfnnfnne." + /* 5 */ ".o........o." + /* 6 */ ".o..r..r..o." + /* 7 */ ".eoofoofooe." /* 8 */ "............" // Level 3 /* z\x* 11 */ /* * 012345678901 */ - /* 0 */ "jjjjjjjjjjjj" + /* 0 */ "kkkkkkkkkkkk" /* 1 */ "sffffffffffs" /* 2 */ ".fttttttttf." /* 3 */ ".f........f." @@ -2809,19 +2809,19 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 5 */ ".f........f." /* 6 */ ".fttttttttf." /* 7 */ "wffffffffffw" - /* 8 */ "hhhhhhhhhhhh" + /* 8 */ "iiiiiiiiiiii" // Level 4 /* z\x* 11 */ /* * 012345678901 */ /* 0 */ "............" - /* 1 */ "jjjjjjjjjjjj" + /* 1 */ "kkkkkkkkkkkk" /* 2 */ "sffffffffffs" /* 3 */ ".fttttttttf." /* 4 */ ".f........f." /* 5 */ ".fttttttttf." /* 6 */ "wffffffffffw" - /* 7 */ "hhhhhhhhhhhh" + /* 7 */ "iiiiiiiiiiii" /* 8 */ "............" // Level 5 @@ -2829,11 +2829,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* * 012345678901 */ /* 0 */ "............" /* 1 */ "............" - /* 2 */ "jjjjjjjjjjjj" + /* 2 */ "kkkkkkkkkkkk" /* 3 */ "sffffffffffs" /* 4 */ ".f........f." /* 5 */ "wffffffffffw" - /* 6 */ "hhhhhhhhhhhh" + /* 6 */ "iiiiiiiiiiii" /* 7 */ "............" /* 8 */ "............" @@ -2843,15 +2843,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 0 */ "............" /* 1 */ "............" /* 2 */ "............" - /* 3 */ "jjjjjjjjjjjj" + /* 3 */ "kkkkkkkkkkkk" /* 4 */ "ffffffffffff" - /* 5 */ "hhhhhhhhhhhh" + /* 5 */ "iiiiiiiiiiii" /* 6 */ "............" /* 7 */ "............" /* 8 */ "............", // Connectors: - "", + "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2895,19 +2895,18 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "f: 2: 0\n" /* grass */ "g: 17: 0\n" /* tree */ "h: 5: 0\n" /* wood */ - "i: 64: 5\n" /* wooddoorblock */ + "i: 64: 7\n" /* wooddoorblock */ "j: 53: 3\n" /* woodstairs */ "k: 85: 0\n" /* fence */ "l: 53: 2\n" /* woodstairs */ "m: 19: 0\n" /* sponge */ - "n: 64: 7\n" /* wooddoorblock */ - "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 */, + "n:102: 0\n" /* glasspane */ + "o: 64:12\n" /* wooddoorblock */ + "p: 72: 0\n" /* woodplate */ + "q: 53: 7\n" /* woodstairs */ + "r: 50: 1\n" /* torch */ + "s: 50: 2\n" /* torch */ + "t: 53: 6\n" /* woodstairs */, // Block data: // Level 0 @@ -2937,7 +2936,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 4 */ ".h.e....lh." /* 5 */ ".h.......h." /* 6 */ ".h.......h." - /* 7 */ ".ghhhnhhhg." + /* 7 */ ".ghhhihhhg." /* 8 */ "..k.....k.." /* 9 */ "mmk.....kmm" /* 10 */ "mmk.....kmm" @@ -2948,13 +2947,13 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ ".goohphoog." - /* 2 */ ".o.......o." - /* 3 */ ".o......qo." + /* 1 */ ".gnnhohnng." + /* 2 */ ".n.......n." + /* 3 */ ".n......pn." /* 4 */ ".h.......h." - /* 5 */ ".o.......o." - /* 6 */ ".o.......o." - /* 7 */ ".goohphoog." + /* 5 */ ".n.......n." + /* 6 */ ".n.......n." + /* 7 */ ".gnnhohnng." /* 8 */ "..........." /* 9 */ "mm.......mm" /* 10 */ "mm.......mm" @@ -2965,13 +2964,13 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "lllllllllll" - /* 1 */ "rhhhhhhhhhr" + /* 1 */ "qhhhhhhhhhq" /* 2 */ ".h.......h." /* 3 */ ".h.......h." - /* 4 */ ".hs.....th." + /* 4 */ ".hr.....sh." /* 5 */ ".h.......h." /* 6 */ ".h.......h." - /* 7 */ "uhhhhhhhhhu" + /* 7 */ "thhhhhhhhht" /* 8 */ "jjjjjjjjjjj" /* 9 */ "mm.......mm" /* 10 */ "mm.......mm" @@ -2983,11 +2982,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* * 01234567890 */ /* 0 */ "..........." /* 1 */ "lllllllllll" - /* 2 */ "rhhhhhhhhhr" + /* 2 */ "qhhhhhhhhhq" /* 3 */ ".h.......h." /* 4 */ ".h.......h." /* 5 */ ".h.......h." - /* 6 */ "uhhhhhhhhhu" + /* 6 */ "thhhhhhhhht" /* 7 */ "jjjjjjjjjjj" /* 8 */ "..........." /* 9 */ "mm.......mm" @@ -3001,9 +3000,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 0 */ "..........." /* 1 */ "..........." /* 2 */ "lllllllllll" - /* 3 */ "rhhhhhhhhhr" + /* 3 */ "qhhhhhhhhhq" /* 4 */ ".h.......h." - /* 5 */ "uhhhhhhhhhu" + /* 5 */ "thhhhhhhhht" /* 6 */ "jjjjjjjjjjj" /* 7 */ "..........." /* 8 */ "..........." @@ -3030,7 +3029,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 12 */ "mm.......mm", // Connectors: - "", + "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -3279,7 +3278,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "f: 5: 0\n" /* wood */ "g: 54: 4\n" /* chest */ "h:154: 4\n" /* hopper */ - "i: 64: 6\n" /* wooddoorblock */ + "i: 64: 4\n" /* wooddoorblock */ "j:102: 0\n" /* glasspane */ "k: 85: 0\n" /* fence */ "l: 64:12\n" /* wooddoorblock */ @@ -3551,7 +3550,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 12 */ ".........", // Connectors: - "", + "-1: 5, 0, 6: 5\n" /* Type -1, direction X+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -3692,7 +3691,10 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] = /* 3 */ "bbbb", // Connectors: - "", + "1: 1, 9, 3: 3\n" /* Type 1, direction Z+ */ + "1: 2, 9, 0: 2\n" /* Type 1, direction Z- */ + "1: 0, 9, 1: 4\n" /* Type 1, direction X- */ + "1: 3, 9, 2: 5\n" /* Type 1, direction X+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ diff --git a/src/Generating/Prefabs/SandVillagePrefabs.cpp b/src/Generating/Prefabs/SandVillagePrefabs.cpp index 23af0f0a6..51411dea2 100644 --- a/src/Generating/Prefabs/SandVillagePrefabs.cpp +++ b/src/Generating/Prefabs/SandVillagePrefabs.cpp @@ -63,7 +63,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ "d.....d.....d", // Connectors: - "", + "-1: 6, 0, 8: 3\n" /* Type -1, direction Z+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -103,7 +103,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "b:128: 2\n" /* sandstonestairs */ "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ - "e: 64: 5\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f:102: 0\n" /* glasspane */ "g: 64:12\n" /* wooddoorblock */ "h:128: 7\n" /* sandstonestairs */ @@ -183,7 +183,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 6 */ "...........", // Connectors: - "", + "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -223,7 +223,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "b:128: 2\n" /* sandstonestairs */ "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ - "e: 64: 5\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f:102: 0\n" /* glasspane */ "g: 64:12\n" /* wooddoorblock */ "h:128: 7\n" /* sandstonestairs */ @@ -326,7 +326,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ "...........", // Connectors: - "", + "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -366,7 +366,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "b:128: 2\n" /* sandstonestairs */ "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ - "e: 64: 5\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f:102: 0\n" /* glasspane */ "g: 64:12\n" /* wooddoorblock */ "h:128: 7\n" /* sandstonestairs */ @@ -444,7 +444,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 6 */ ".............", // Connectors: - "", + "-1: 6, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -484,7 +484,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "b:128: 2\n" /* sandstonestairs */ "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ - "e: 64: 5\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f:102: 0\n" /* glasspane */ "g: 64:12\n" /* wooddoorblock */ "h:128: 7\n" /* sandstonestairs */ @@ -587,7 +587,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ ".............", // Connectors: - "", + "-1: 6, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -627,7 +627,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "b:128: 2\n" /* sandstonestairs */ "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ - "e: 64: 5\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f:102: 0\n" /* glasspane */ "g: 64:12\n" /* wooddoorblock */ "h:128: 7\n" /* sandstonestairs */ @@ -730,7 +730,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ "...............", // Connectors: - "", + "-1: 6, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -770,7 +770,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "b:128: 2\n" /* sandstonestairs */ "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ - "e: 64: 5\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f:102: 0\n" /* glasspane */ "g: 64:12\n" /* wooddoorblock */ "h:128: 7\n" /* sandstonestairs */ @@ -873,7 +873,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ "................", // Connectors: - "", + "-1: 9, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -913,7 +913,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "b:128: 2\n" /* sandstonestairs */ "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ - "e: 64: 5\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f:102: 0\n" /* glasspane */ "g: 64:12\n" /* wooddoorblock */ "h:128: 7\n" /* sandstonestairs */ @@ -984,7 +984,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 6 */ ".......", // Connectors: - "", + "-1: 4, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1024,7 +1024,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "b:128: 2\n" /* sandstonestairs */ "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ - "e: 64: 5\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f:102: 0\n" /* glasspane */ "g: 64:12\n" /* wooddoorblock */ "h:128: 7\n" /* sandstonestairs */ @@ -1096,7 +1096,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 6 */ ".........", // Connectors: - "", + "-1: 4, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1136,9 +1136,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "b:128: 2\n" /* sandstonestairs */ "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ - "e: 64: 1\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f:102: 0\n" /* glasspane */ - "g: 64: 8\n" /* wooddoorblock */ + "g: 64:12\n" /* wooddoorblock */ "h:128: 7\n" /* sandstonestairs */ "i: 50: 3\n" /* torch */ "j: 50: 4\n" /* torch */ @@ -1232,7 +1232,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ ".........", // Connectors: - "", + "-1: 4, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1273,17 +1273,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ "e:128: 3\n" /* sandstonestairs */ - "f: 64: 5\n" /* wooddoorblock */ - "g:102: 0\n" /* glasspane */ - "h: 64:12\n" /* wooddoorblock */ - "i:128: 7\n" /* sandstonestairs */ - "j: 50: 3\n" /* torch */ - "k: 50: 4\n" /* torch */ - "l:128: 6\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: 5\n" /* sandstonestairs */ - "o:128: 4\n" /* sandstonestairs */ - "p: 50: 1\n" /* torch */, + "n:128: 6\n" /* sandstonestairs */ + "o:128: 5\n" /* sandstonestairs */ + "p:128: 4\n" /* sandstonestairs */ + "q: 50: 1\n" /* torch */, // Block data: // Level 0 @@ -1310,7 +1311,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 2 */ ".d..........d." /* 3 */ ".d..........d." /* 4 */ ".d..........d." - /* 5 */ ".ddddfddd...d." + /* 5 */ ".ddddgddd...d." /* 6 */ "........d...d." /* 7 */ "mmmmmmm.d...d." /* 8 */ "mmmmmmm.d...d." @@ -1322,49 +1323,49 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* z\x* 1111 */ /* * 01234567890123 */ /* 0 */ ".............." - /* 1 */ ".dggdggdhdggd." - /* 2 */ ".g..........g." - /* 3 */ ".g..........g." - /* 4 */ ".g..........d." - /* 5 */ ".dggdhdgg...g." - /* 6 */ "........g...g." + /* 1 */ ".dhhdhhdidhhd." + /* 2 */ ".h..........h." + /* 3 */ ".h..........h." + /* 4 */ ".h..........d." + /* 5 */ ".dhhdidhh...h." + /* 6 */ "........h...h." /* 7 */ "mmmmmmm.d...d." - /* 8 */ "mmmmmmm.g...g." - /* 9 */ "mmmmmmm.g...g." - /* 10 */ "mmmmmmm.dgggd." + /* 8 */ "mmmmmmm.h...h." + /* 9 */ "mmmmmmm.h...h." + /* 10 */ "mmmmmmm.dhhhd." /* 11 */ "mmmmmmm......." // Level 3 /* z\x* 1111 */ /* * 01234567890123 */ /* 0 */ "bbbbbbbbbbbbbb" - /* 1 */ "iddddddddddddc" - /* 2 */ ".d.....j.j..dc" + /* 1 */ "jddddddddddddc" + /* 2 */ ".d.....k.k..dc" /* 3 */ ".d..........dc" - /* 4 */ ".d..k.k.....dc" - /* 5 */ "ldddddddd...dc" + /* 4 */ ".d..l.l.....dc" + /* 5 */ "ndddddddd...dc" /* 6 */ "eeeeeeead...dc" /* 7 */ "mmmmmmmad...dc" /* 8 */ "mmmmmmmad...dc" /* 9 */ "mmmmmmmad...dc" /* 10 */ "mmmmmmmadddddc" - /* 11 */ "mmmmmmman...oc" + /* 11 */ "mmmmmmmao...pc" // Level 4 /* z\x* 1111 */ /* * 01234567890123 */ /* 0 */ ".............." /* 1 */ "bbbbbbbbbbbbb." - /* 2 */ "idddddddddddc." - /* 3 */ ".dp........dc." - /* 4 */ "lddddddddd.dc." + /* 2 */ "jdddddddddddc." + /* 3 */ ".dq........dc." + /* 4 */ "nddddddddd.dc." /* 5 */ "eeeeeeeead.dc." /* 6 */ "........ad.dc." /* 7 */ "mmmmmmm.ad.dc." /* 8 */ "mmmmmmm.ad.dc." - /* 9 */ "mmmmmmm.adkdc." + /* 9 */ "mmmmmmm.adldc." /* 10 */ "mmmmmmm.adddc." - /* 11 */ "mmmmmmm.an.oc." + /* 11 */ "mmmmmmm.ao.pc." // Level 5 /* z\x* 1111 */ @@ -1383,7 +1384,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 11 */ "mmmmmmm..adc..", // Connectors: - "", + "-1: 8, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1424,19 +1425,18 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "c:128: 1\n" /* sandstonestairs */ "d: 24: 0\n" /* sandstone */ "e:128: 3\n" /* sandstonestairs */ - "f: 64: 5\n" /* wooddoorblock */ - "g: 64: 7\n" /* wooddoorblock */ - "h:102: 0\n" /* glasspane */ - "i: 64:12\n" /* wooddoorblock */ - "j:128: 7\n" /* sandstonestairs */ - "k: 50: 3\n" /* torch */ - "l: 50: 2\n" /* torch */ + "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: 50: 4\n" /* torch */ - "o:128: 6\n" /* sandstonestairs */ - "p: 50: 1\n" /* torch */ - "q:128: 5\n" /* sandstonestairs */ - "r:128: 4\n" /* sandstonestairs */, + "n:128: 6\n" /* sandstonestairs */ + "o: 50: 1\n" /* torch */ + "p:128: 5\n" /* sandstonestairs */ + "q:128: 4\n" /* sandstonestairs */, // Block data: // Level 0 @@ -1465,7 +1465,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 4 */ ".d..........d." /* 5 */ ".d..........d." /* 6 */ ".d..........d." - /* 7 */ ".ddddgd.....d." + /* 7 */ ".ddddfd.....d." /* 8 */ "......d.....d." /* 9 */ "mmmmm.d.....d." /* 10 */ "mmmmm.ddddddd." @@ -1475,49 +1475,49 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* z\x* 1111 */ /* * 01234567890123 */ /* 0 */ ".............." - /* 1 */ ".dhhdidhhdhhd." - /* 2 */ ".h..........h." - /* 3 */ ".h..........h." + /* 1 */ ".dggdhdggdggd." + /* 2 */ ".g..........g." + /* 3 */ ".g..........g." /* 4 */ ".d..........d." - /* 5 */ ".h..........h." - /* 6 */ ".h..........h." - /* 7 */ ".dhhdid.....d." - /* 8 */ "......h.....h." - /* 9 */ "mmmmm.h.....h." - /* 10 */ "mmmmm.dhhdhhd." + /* 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 */ "jddddddddddddc" - /* 2 */ ".d..k.k.....dc" + /* 1 */ "iddddddddddddc" + /* 2 */ ".d..j.j.....dc" /* 3 */ ".d..........dc" - /* 4 */ ".d.........ldc" + /* 4 */ ".d.........kdc" /* 5 */ ".d..........dc" - /* 6 */ ".d..n.n.....dc" - /* 7 */ "oddddddp...ldc" + /* 6 */ ".d..l.l.....dc" + /* 7 */ "nddddddo...kdc" /* 8 */ "eeeeead.....dc" /* 9 */ "mmmmmad.....dc" /* 10 */ "mmmmmadddddddc" - /* 11 */ "mmmmmaq.....rc" + /* 11 */ "mmmmmap.....qc" // Level 4 /* z\x* 1111 */ /* * 01234567890123 */ /* 0 */ ".............." /* 1 */ "bbbbbbbbbbbbc." - /* 2 */ "jdddddddddddc." + /* 2 */ "idddddddddddc." /* 3 */ ".d.........dc." /* 4 */ ".d.........dc." /* 5 */ ".d.........dc." - /* 6 */ "oddddddd...dc." + /* 6 */ "nddddddd...dc." /* 7 */ "eeeeeead...dc." /* 8 */ "......ad...dc." /* 9 */ "mmmmm.ad...dc." /* 10 */ "mmmmm.adddddc." - /* 11 */ "mmmmm.aq...rc." + /* 11 */ "mmmmm.ap...qc." // Level 5 /* z\x* 1111 */ @@ -1525,15 +1525,15 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 0 */ ".............." /* 1 */ ".............." /* 2 */ "bbbbbbbbbbbb.." - /* 3 */ "jddddddddddc.." + /* 3 */ "iddddddddddc.." /* 4 */ ".d........dc.." - /* 5 */ "odddddddd.dc.." + /* 5 */ "ndddddddd.dc.." /* 6 */ "eeeeeeeed.dc.." /* 7 */ ".......ad.dc.." /* 8 */ ".......ad.dc.." /* 9 */ "mmmmm..ad.dc.." /* 10 */ "mmmmm..adddc.." - /* 11 */ "mmmmm..aq.rc.." + /* 11 */ "mmmmm..ap.qc.." // Level 6 /* z\x* 1111 */ @@ -1552,7 +1552,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 11 */ "mmmmm...adc...", // Connectors: - "", + "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1619,7 +1619,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 6 */ "d........d", // Connectors: - "", + "-1: 0, 0, 3: 4\n" /* Type -1, direction X- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1661,8 +1661,8 @@ const cPrefab::sDef g_SandVillagePrefabs[] = "d: 50: 5\n" /* torch */ "e: 26:10\n" /* bedblock */ "f: 26: 2\n" /* bedblock */ - "g: 64: 3\n" /* wooddoorblock */ - "h: 64: 8\n" /* wooddoorblock */ + "g: 64: 5\n" /* wooddoorblock */ + "h: 64:12\n" /* wooddoorblock */ "m: 19: 0\n" /* sponge */, // Block data: @@ -1712,7 +1712,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 5 */ ".....", // Connectors: - "", + "-1: 2, 0, 4: 3\n" /* Type -1, direction Z+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1853,7 +1853,10 @@ const cPrefab::sDef g_SandVillageStartingPrefabs[] = /* 3 */ "bbbb", // Connectors: - "", + "1: 2, 8, 0: 2\n" /* Type 1, direction Z- */ + "1: 0, 8, 1: 4\n" /* Type 1, direction X- */ + "1: 1, 8, 3: 3\n" /* Type 1, direction Z+ */ + "1: 3, 8, 2: 5\n" /* Type 1, direction X+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index 3d89d7aa2..3358bc531 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -7,6 +7,7 @@ #include "VillageGen.h" #include "Prefabs/PlainsVillagePrefabs.h" #include "Prefabs/SandVillagePrefabs.h" +#include "PieceGenerator.h" @@ -19,18 +20,79 @@ the grid's cells. Each cell checks the biomes in an entire chunk around it, only 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 starting by its well. The well is placed in the grid's origin point. Then a set of -random lengths roads is generated - 4 roads going from the well, then at the end of each road another set of -roads, crossing them perpendicular, then at the end of those another set, up to a set maximum branching -depth. The roads are placed in a T or L shape, with the old road being the center stem of the T. Roads avoid -crossing each other and going further away from the well than the maximum block size of the village. -Finally, houses are places along the roads, avoiding collisions with already-existing items. +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. -When the village is about to be drawn into a chunk, it queries the heights for each item intersecting the -chunk. The prefabs are shifted so that their pivot points lie on the surface, and the roads are drawn +The well has connectors of type "1". The houses have connectors of type "-1". The roads have connectors of +both types, type "-1" at the far ends and type "1" on the long edges. + +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. */ +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 piece: + cBlockArea BA; + BA.Create(5, 1, 3, cBlockArea::baTypes | cBlockArea::baMetas); + BA.Fill(cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_GRAVEL, 0); + cPrefab * RoadPiece = new cPrefab(BA, 7); + RoadPiece->AddConnector(0, 0, 1, BLOCK_FACE_XM, -1); + RoadPiece->AddConnector(4, 0, 1, BLOCK_FACE_XP, -1); + RoadPiece->AddConnector(4, 0, 1, BLOCK_FACE_XP, 1); + RoadPiece->AddConnector(1, 0, 0, BLOCK_FACE_ZM, 1); + RoadPiece->AddConnector(3, 0, 0, BLOCK_FACE_ZM, 1); + RoadPiece->AddConnector(1, 0, 2, BLOCK_FACE_ZP, 1); + RoadPiece->AddConnector(3, 0, 2, BLOCK_FACE_ZP, 1); + RoadPiece->SetAddWeightIfSame(10000); + m_AllPieces.push_back(RoadPiece); + m_PiecesByConnector[-1].push_back(RoadPiece); + m_PiecesByConnector[1].push_back(RoadPiece); + } + + + // cPrefabPiecePool overrides: + virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override + { + // Only roads are allowed to connect to the well: + if ((a_PlacedPiece.GetDepth() == 0) && (a_NewPiece.GetSize().y != 1)) + { + return 0; + } + + // Roads cannot branch T-wise: + if ( + (a_PlacedPiece.GetPiece().GetSize().y == 1) && // Connecting to a road + ( + (a_ExistingConnector.m_Direction == BLOCK_FACE_ZP) || + (a_ExistingConnector.m_Direction == BLOCK_FACE_ZM) + ) && // Through the long-edge connector + (a_NewPiece.GetSize().y == 1) // And the new piece is a road + ) + { + return 0; + } + + return ((const cPrefab &)a_NewPiece).GetPieceWeight(a_PlacedPiece, a_ExistingConnector); + } +} ; + + + + + class cVillageGen::cVillage : public cGridStructGen::cStructure { @@ -53,44 +115,11 @@ public: m_Prefabs(a_Prefabs), m_HeightGen(a_HeightGen) { - PlaceWell(); - BuildRoads(a_MaxRoadDepth); - PlaceHouses(); + cBFSPieceGenerator pg(m_Prefabs, a_Seed); + pg.PlacePieces(a_OriginX, 10, a_OriginZ, a_MaxRoadDepth + 1, m_Pieces); } protected: - class cItem - { - public: - /* The position of the item, X/Z-wise: */ - int m_MinX, m_MaxX, m_MinZ, m_MaxZ; - - /** The prefab to use. If NULL, this is a road. */ - cPrefab * m_Prefab; - - /** Number of rotations that should be applied to the prefab. */ - int m_NumRotations; - - /* The bottom of the prefab. Only valid if the item is a prefab, not valid for roads. */ - int m_BaseY; - - /** Creates a new item with the specified parameters. - m_BaseY is set to -1 and will be adjusted later on when drawing. */ - cItem(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, cPrefab * a_Prefab, int a_NumRotations) : - m_MinX(a_MinX), - m_MaxX(a_MaxX), - m_MinZ(a_MinZ), - m_MaxZ(a_MaxZ), - m_Prefab(a_Prefab), - m_NumRotations(a_NumRotations), - m_BaseY(-1) - { - } - } ; - typedef SharedPtr cItemPtr; - typedef std::vector cItemPtrs; - - /** Seed for the random functions */ int m_Seed; @@ -109,61 +138,8 @@ protected: /** The underlying height generator, used for placing the structures on top of the terrain. */ cTerrainHeightGen & m_HeightGen; - /** The items that are generated in the village (houses, roads). */ - cItemPtrs m_Items; - - - /** Places the well at the center of the village */ - void PlaceWell(void) - { - // Pick a prefab from the starting pieces: - cPieces StartingPieces = ((cPiecePool &)m_Prefabs).GetStartingPieces(); - ASSERT(!StartingPieces.empty()); - int TotalWeight = 0; - for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr) - { - TotalWeight += ((const cPrefab *)(*itr))->GetDefaultWeight(); - } - ASSERT(TotalWeight > 0); - int rnd = (m_Noise.IntNoise2DInt(m_OriginX, m_OriginZ) / 7) % TotalWeight; - cPiece * WellPiece = StartingPieces[0]; - for (cPieces::const_iterator itr = StartingPieces.begin(), end = StartingPieces.end(); itr != end; ++itr) - { - rnd -= ((const cPrefab *)(*itr))->GetDefaultWeight(); - if (rnd <= 0) - { - WellPiece = *itr; - break; - } - } - ASSERT(WellPiece != NULL); - - // Pick a rotation: - // TODO - int NumRotations = 0; - Vector3i Size = WellPiece->GetSize(); - - // Put the well in the placed items array: - m_Items.push_back(cItemPtr(new cItem(m_OriginX, m_OriginX + Size.x, m_OriginZ, m_OriginZ + Size.z, (cPrefab *)WellPiece, NumRotations))); - } - - - /** Places the roads going from the well outwards. */ - void BuildRoads(int a_MaxRoadDepth) - { - /* - ASSERT(m_Items.size() == 1); - const cItem & Well = *m_Items[0]; - */ - // TODO - } - - - /** Places houses along the roads. */ - void PlaceHouses(void) - { - // TODO - } + /** The village pieces, placed by the generator. */ + cPlacedPieces m_Pieces; // cGrdStructGen::cStructure overrides: @@ -173,6 +149,11 @@ protected: // Iterate over all items // Each intersecting prefab is placed on ground (if not already placed), then drawn // Each intersecting road is drawn by replacing top soil blocks with gravel / sandstone blocks + for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) + { + const cPrefab & Prefab = (const cPrefab &)((*itr)->GetPiece()); + Prefab.Draw(a_Chunk, *itr); + } // for itr - m_PlacedPieces[] } } ; @@ -183,15 +164,20 @@ protected: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cVillageGen: -cPrefabPiecePool cVillageGen::m_SandVillage (g_SandVillagePrefabs, g_SandVillagePrefabsCount, g_SandVillageStartingPrefabs, g_SandVillageStartingPrefabsCount); -cPrefabPiecePool cVillageGen::m_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVillagePrefabsCount, g_PlainsVillageStartingPrefabs, g_PlainsVillageStartingPrefabsCount); +/** The prefabs for the sand village. */ +static cVillagePiecePool g_SandVillage (g_SandVillagePrefabs, g_SandVillagePrefabsCount, g_SandVillageStartingPrefabs, g_SandVillageStartingPrefabsCount); + +/** The prefabs for the plains village. */ +static cVillagePiecePool g_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVillagePrefabsCount, g_PlainsVillageStartingPrefabs, g_PlainsVillageStartingPrefabsCount); -cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxRoadDepth, int a_MaxSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) : +cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) : super(a_Seed, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 100), + m_MaxDepth(a_MaxDepth), + m_MaxSize(a_MaxSize), m_BiomeGen(a_BiomeGen), m_HeightGen(a_HeightGen) { @@ -211,7 +197,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ // 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 - cPrefabPiecePool * VillagePrefabs = NULL; + cVillagePiecePool * VillagePrefabs = NULL; for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++) { switch (Biomes[i]) @@ -220,7 +206,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ case biDesertM: { // These biomes allow sand villages - VillagePrefabs = &m_SandVillage; + VillagePrefabs = &g_SandVillage; break; } case biPlains: @@ -229,7 +215,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ case biSunflowerPlains: { // These biomes allow plains-style villages - VillagePrefabs = &m_PlainsVillage; + VillagePrefabs = &g_PlainsVillage; break; } default: @@ -245,7 +231,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ { return cStructurePtr(); } - return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxRoadDepth, m_MaxSize, *VillagePrefabs, m_HeightGen)); + return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, *VillagePrefabs, m_HeightGen)); } diff --git a/src/Generating/VillageGen.h b/src/Generating/VillageGen.h index acbd76881..c6f8f024a 100644 --- a/src/Generating/VillageGen.h +++ b/src/Generating/VillageGen.h @@ -21,19 +21,13 @@ class cVillageGen : { typedef cGridStructGen super; public: - cVillageGen(int a_Seed, int a_GridSize, int a_MaxRoadDepth, int a_MaxSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen); + cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen); protected: class cVillage; // fwd: VillageGen.cpp - /** The prefabs for the sand village. We're not exactly using the cPiecePool functionality, only the containment. */ - static cPrefabPiecePool m_SandVillage; - - /** The prefabs for the plains village. We're not exactly using the cPiecePool functionality, only the containment. */ - static cPrefabPiecePool m_PlainsVillage; - - /** Maximum number of roads generated one from another (tree depth). */ - int m_MaxRoadDepth; + /** 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; From 34e5f0c16422f93d3f8f0f802522fa113fa9aa20 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 May 2014 10:43:54 +0200 Subject: [PATCH 052/312] Changed village road generation to use multiple prefabs. --- .../Prefabs/PlainsVillagePrefabs.cpp | 8 +-- src/Generating/Prefabs/SandVillagePrefabs.cpp | 8 +-- src/Generating/VillageGen.cpp | 61 +++++++++---------- 3 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp index 508f0d3b6..06b1395c5 100644 --- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -3691,10 +3691,10 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] = /* 3 */ "bbbb", // Connectors: - "1: 1, 9, 3: 3\n" /* Type 1, direction Z+ */ - "1: 2, 9, 0: 2\n" /* Type 1, direction Z- */ - "1: 0, 9, 1: 4\n" /* Type 1, direction X- */ - "1: 3, 9, 2: 5\n" /* Type 1, direction X+ */, + "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 */ diff --git a/src/Generating/Prefabs/SandVillagePrefabs.cpp b/src/Generating/Prefabs/SandVillagePrefabs.cpp index 51411dea2..8460ee5f7 100644 --- a/src/Generating/Prefabs/SandVillagePrefabs.cpp +++ b/src/Generating/Prefabs/SandVillagePrefabs.cpp @@ -1853,10 +1853,10 @@ const cPrefab::sDef g_SandVillageStartingPrefabs[] = /* 3 */ "bbbb", // Connectors: - "1: 2, 8, 0: 2\n" /* Type 1, direction Z- */ - "1: 0, 8, 1: 4\n" /* Type 1, direction X- */ - "1: 1, 8, 3: 3\n" /* Type 1, direction Z+ */ - "1: 3, 8, 2: 5\n" /* Type 1, direction X+ */, + "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 */ diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index 3358bc531..b514a90cd 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -44,43 +44,42 @@ public: ) : super(a_PieceDefs, a_NumPieceDefs, a_StartingPieceDefs, a_NumStartingPieceDefs) { - // Add the road piece: - cBlockArea BA; - BA.Create(5, 1, 3, cBlockArea::baTypes | cBlockArea::baMetas); - BA.Fill(cBlockArea::baTypes | cBlockArea::baMetas, E_BLOCK_GRAVEL, 0); - cPrefab * RoadPiece = new cPrefab(BA, 7); - RoadPiece->AddConnector(0, 0, 1, BLOCK_FACE_XM, -1); - RoadPiece->AddConnector(4, 0, 1, BLOCK_FACE_XP, -1); - RoadPiece->AddConnector(4, 0, 1, BLOCK_FACE_XP, 1); - RoadPiece->AddConnector(1, 0, 0, BLOCK_FACE_ZM, 1); - RoadPiece->AddConnector(3, 0, 0, BLOCK_FACE_ZM, 1); - RoadPiece->AddConnector(1, 0, 2, BLOCK_FACE_ZP, 1); - RoadPiece->AddConnector(3, 0, 2, BLOCK_FACE_ZP, 1); - RoadPiece->SetAddWeightIfSame(10000); - m_AllPieces.push_back(RoadPiece); - m_PiecesByConnector[-1].push_back(RoadPiece); - m_PiecesByConnector[1].push_back(RoadPiece); + // Add the road pieces: + for (int len = 19; len < 60; len += 8) + { + 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); + + // Add the road connectors: + for (int x = 1; x < len; x += 8) + { + 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 = 5; x < len; x += 8) + { + 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 { - // Only roads are allowed to connect to the well: - if ((a_PlacedPiece.GetDepth() == 0) && (a_NewPiece.GetSize().y != 1)) - { - return 0; - } - - // Roads cannot branch T-wise: - if ( - (a_PlacedPiece.GetPiece().GetSize().y == 1) && // Connecting to a road - ( - (a_ExistingConnector.m_Direction == BLOCK_FACE_ZP) || - (a_ExistingConnector.m_Direction == BLOCK_FACE_ZM) - ) && // Through the long-edge connector - (a_NewPiece.GetSize().y == 1) // And the new piece is a road - ) + // Roads cannot branch T-wise (appending -2 connector to a +2 connector): + if ((a_ExistingConnector.m_Type == 2) && (a_PlacedPiece.GetDepth() > 0)) { return 0; } From 56f7ad2cd9f1bfd69502918ebe760748e453959d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 May 2014 10:44:08 +0200 Subject: [PATCH 053/312] Changed village generator defaults to more reasonable values. --- src/Generating/ComposableGenerator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 1bb836684..f264599c9 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -408,8 +408,8 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) } else if (NoCaseCompare(*itr, "Villages") == 0) { - int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 256); - int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 7); + int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384); + int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 3); int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxDepth, MaxSize, *m_BiomeGen, *m_HeightGen)); } From 70b0547499c4343e3071a54e3c093712669a3a8f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 15 May 2014 16:03:45 +0200 Subject: [PATCH 054/312] Fixed a NULL ptr failure in GridStructGen. When the descendant generator returned a NULL structure, the generator would crash. Now it uses a special cEmptyStructure class instead. --- src/Generating/GridStructGen.cpp | 35 +++++++++++++++++++++++++++++++- src/Generating/GridStructGen.h | 16 +++++++-------- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp index 3bbc89054..23946e2e9 100644 --- a/src/Generating/GridStructGen.cpp +++ b/src/Generating/GridStructGen.cpp @@ -9,6 +9,34 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// 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_OriginX, int a_OriginZ) : + super(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, @@ -81,7 +109,12 @@ void cGridStructGen::GetStructuresForChunk(int a_ChunkX, int a_ChunkZ, cStructur } // for itr - a_Structures[] if (!Found) { - a_Structures.push_back(CreateStructure(OriginX, OriginZ)); + cStructurePtr Structure = CreateStructure(OriginX, OriginZ); + if (Structure.get() == NULL) + { + Structure.reset(new cEmptyStructure(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..630a5e44e 100644 --- a/src/Generating/GridStructGen.h +++ b/src/Generating/GridStructGen.h @@ -39,14 +39,6 @@ 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 { @@ -75,6 +67,14 @@ protected: typedef std::list cStructurePtrs; + cGridStructGen( + int a_Seed, + int a_GridSizeX, int a_GridSizeZ, + int a_MaxStructureSizeX, int a_MaxStructureSizeZ, + size_t a_MaxCacheSize + ); + +protected: /** Seed for generating the semi-random grid. */ int m_Seed; From 989312c4e7f517ae324e857cb255211e3fd8bb06 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 16 May 2014 22:04:19 +0200 Subject: [PATCH 055/312] Add more move checks - Invalid X/Y/Z/Stance check (std::isnan) - Illegal stance - Illegal position (32.000.000 is the world size) --- src/ClientHandle.cpp | 74 ++++++++++++++++++++++++++++++++++---------- src/ClientHandle.h | 2 +- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 0c897374b..41b5d1626 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -582,16 +582,37 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, return; } - /* - // TODO: Invalid stance check - if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65)) + if (m_Player->GetHealth() <= 0) { - LOGD("Invalid stance"); - SendPlayerMoveLook(); + // The player is dead. He can't move :D return; } - */ - + + if (std::isnan(a_PosX) || std::isnan(a_PosY) || std::isnan(a_PosZ) || std::isnan(a_Stance)) + { + LOGWARN("%s was caught trying to crash the server with an invalid position.", m_Player->GetName().c_str()); + Kick("Nope!"); + return; + } + + // Invalid stance check + if (!m_Player->IsInBed()) + { + double Difference = a_Stance - a_PosY; + if ((Difference > 1.65) || (Difference < 1.0)) + { + Kick("Illegal stance!"); + LOGWARN("%s had an illegal stance: %f", m_Player->GetName().c_str(), a_Stance); + return; + } + } + + if ((std::abs(a_PosX) > 32000000.0) || (std::abs(a_PosZ) > 32000000.0)) + { + Kick("Illegal position!"); + return; + } + // If the player has moved too far, "repair" them: Vector3d Pos(a_PosX, a_PosY, a_PosZ); if ((m_Player->GetPosition() - Pos).SqrLength() > 100 * 100) @@ -1388,7 +1409,7 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO -void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround) +void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Yaw, float a_Pitch, bool a_IsOnGround) { if ((m_Player == NULL) || (m_State != csPlaying)) { @@ -1396,21 +1417,42 @@ void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_ return; } - /* - // TODO: Invalid stance check - if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65)) + if (m_Player->GetHealth() <= 0) { - LOGD("Invalid stance"); - SendPlayerMoveLook(); + // The player is dead. He can't move :D + return; + } + + if (std::isnan(a_PosX) || std::isnan(a_PosY) || std::isnan(a_PosZ) || std::isnan(a_Stance)) + { + LOGWARN("%s was caught trying to crash the server with an invalid position.", m_Player->GetName().c_str()); + Kick("Nope!"); + return; + } + + // Invalid stance check + if (!m_Player->IsInBed()) + { + double Difference = a_Stance - a_PosY; + if ((Difference > 1.65) || (Difference < 1.0)) + { + Kick("Illegal stance!"); + LOGWARN("%s had an illegal stance: %f", m_Player->GetName().c_str(), a_Stance); + return; + } + } + + if ((std::abs(a_PosX) > 32000000.0) || (std::abs(a_PosZ) > 32000000.0)) + { + Kick("Illegal position!"); return; } - */ m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ)); m_Player->SetStance (a_Stance); m_Player->SetTouchGround(a_IsOnGround); - m_Player->SetHeadYaw (a_Rotation); - m_Player->SetYaw (a_Rotation); + m_Player->SetHeadYaw (a_Yaw); + m_Player->SetYaw (a_Yaw); m_Player->SetPitch (a_Pitch); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 85d348eee..940fb786a 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -223,7 +223,7 @@ public: void HandlePing (void); void HandlePlayerAbilities (bool a_CanFly, bool a_IsFlying, float FlyingSpeed, float WalkingSpeed); void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround); - void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay) + void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Yaw, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay) void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround); void HandlePluginMessage (const AString & a_Channel, const AString & a_Message); void HandleRespawn (void); From fc5c3abcba9153196727a77e726bb0b37d5c7450 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 17 May 2014 02:26:44 +0200 Subject: [PATCH 056/312] Updated PlainsVillage prefabs to the latest Gallery contents. --- .../Prefabs/PlainsVillagePrefabs.cpp | 6429 +++++++++-------- 1 file changed, 3528 insertions(+), 2901 deletions(-) diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp index 06b1395c5..863720ab4 100644 --- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -16,165 +16,95 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Forge: - // The data has been exported from the gallery Plains, area index 51, ID 102, created by Aloe_vera + // BigPlantBed: + // The data has been exported from the gallery Plains, area index 26, ID 70, created by Taugrammaton { // Size: - 12, 8, 11, // SizeX = 12, SizeY = 8, SizeZ = 11 + 13, 4, 12, // SizeX = 13, SizeY = 4, SizeZ = 12 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 11, 7, 10, // MaxX, MaxY, MaxZ + 12, 3, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */, + "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 */ + "m: 19: 0\n" /* sponge */, // Block data: // Level 0 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ ".....abbbc.." - /* 1 */ ".ddddddddc.." - /* 2 */ ".ddddddddc.." - /* 3 */ ".ddddddddddd" - /* 4 */ ".ddddddddddd" - /* 5 */ ".ddddddddddd" - /* 6 */ ".ddddddddddd" - /* 7 */ ".ddddddddddd" - /* 8 */ ".ddddd.mmmmm" - /* 9 */ ".ddddd.mmmmm" - /* 10 */ ".......mmmmm" + /* 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* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ ".efffe......" - /* 2 */ ".f...g......" - /* 3 */ ".f...ed..ddd" - /* 4 */ ".f...f...dhd" - /* 5 */ ".f...f...dhd" - /* 6 */ ".f...fijjdhd" - /* 7 */ ".f...edddddd" - /* 8 */ ".f...f.mmmmm" - /* 9 */ ".efffe.mmmmm" - /* 10 */ ".......mmmmm" + /* 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* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ ".ekkke......" - /* 2 */ ".k...l......" - /* 3 */ ".k...en..n.d" - /* 4 */ ".k...k.....o" - /* 5 */ ".f...k.....o" - /* 6 */ ".k...k.....o" - /* 7 */ ".k...edooood" - /* 8 */ ".k...f.mmmmm" - /* 9 */ ".ekkke.mmmmm" - /* 10 */ ".......mmmmm" + /* 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* 11 */ - /* * 012345678901 */ - /* 0 */ "ppppppp....." - /* 1 */ "qfffffq....." - /* 2 */ ".f...f......" - /* 3 */ ".f..rfd..dod" - /* 4 */ ".f...f...o.d" - /* 5 */ ".f...f...o.d" - /* 6 */ ".fs..f...o.d" - /* 7 */ ".f...fdddddd" - /* 8 */ ".f...f.mmmmm" - /* 9 */ "tffffftmmmmm" - /* 10 */ "uuuuuuummmmm" - - // Level 4 - /* 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 */ "tffffftmmmmm" - /* 9 */ "uuuuuuummmmm" - /* 10 */ ".......mmmmm" - - // Level 5 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "............" - /* 2 */ "ppppppp....." - /* 3 */ "qfffffq....." - /* 4 */ ".f...f......" - /* 5 */ ".f...f......" - /* 6 */ ".f...f......" - /* 7 */ "tffffft....." - /* 8 */ "uuuuuuummmmm" - /* 9 */ ".......mmmmm" - /* 10 */ ".......mmmmm" - - // Level 6 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "............" - /* 2 */ "............" - /* 3 */ "ppppppp....." - /* 4 */ "qfffffq....." - /* 5 */ ".f...f......" - /* 6 */ "tffffft....." - /* 7 */ "uuuuuuu....." - /* 8 */ ".......mmmmm" - /* 9 */ ".......mmmmm" - /* 10 */ ".......mmmmm" - - // Level 7 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "............" - /* 2 */ "............" - /* 3 */ "............" - /* 4 */ "ppppppp....." - /* 5 */ "fffffff....." - /* 6 */ "uuuuuuu....." - /* 7 */ "............" - /* 8 */ ".......mmmmm" - /* 9 */ ".......mmmmm" - /* 10 */ ".......mmmmm", + /* 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", // Connectors: - "-1: 7, 0, 0: 2\n" /* Type -1, direction Z- */, + "-1: 7, 1, 11: 3\n" /* Type -1, direction Z+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -193,539 +123,139 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, - }, // Forge + }, // BigPlantBed /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_100: - // The data has been exported from the gallery Plains, area index 49, ID 100, created by Aloe_vera + // CobbleHouse10x5Library: + // The data has been exported from the gallery Plains, area index 23, ID 66, created by xoft { // Size: - 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7 + 12, 8, 7, // SizeX = 12, SizeY = 8, SizeZ = 7 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 6, 5, 6, // MaxX, MaxY, MaxZ + 11, 7, 6, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "e: 17: 0\n" /* tree */ - "f: 5: 0\n" /* wood */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ "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 */ + "h: 53: 3\n" /* woodstairs */ + "i: 53: 1\n" /* woodstairs */ + "j: 85: 0\n" /* fence */ + "k: 53: 0\n" /* woodstairs */ + "l: 53: 2\n" /* woodstairs */ "m: 19: 0\n" /* sponge */ - "n: 53: 6\n" /* woodstairs */ - "o: 53: 3\n" /* woodstairs */, - - // 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 */ ".efgfe." - /* 2 */ ".f...f." - /* 3 */ ".f...f." - /* 4 */ ".f...f." - /* 5 */ ".efffe." - /* 6 */ "......." - - // Level 2 - /* z\x* 0123456 */ - /* 0 */ "......." - /* 1 */ ".efhfe." - /* 2 */ ".i...i." - /* 3 */ ".i...i." - /* 4 */ ".i...i." - /* 5 */ ".eiiie." - /* 6 */ "......." - - // Level 3 - /* z\x* 0123456 */ - /* 0 */ "jjjjjjj" - /* 1 */ "kfffffk" - /* 2 */ ".fl.lf." - /* 3 */ ".f...f." - /* 4 */ ".f...f." - /* 5 */ "nfffffn" - /* 6 */ "ooooooo" - - // Level 4 - /* z\x* 0123456 */ - /* 0 */ "......." - /* 1 */ "jjjjjjj" - /* 2 */ "kfffffk" - /* 3 */ ".f...f." - /* 4 */ "nfffffn" - /* 5 */ "ooooooo" - /* 6 */ "......." - - // Level 5 - /* z\x* 0123456 */ - /* 0 */ "......." - /* 1 */ "......." - /* 2 */ "jjjjjjj" - /* 3 */ "fffffff" - /* 4 */ "ooooooo" - /* 5 */ "......." - /* 6 */ ".......", - - // Connectors: - "-1: 3, 0, 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, - }, // PlainsVillage_100 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_103: - // The data has been exported from the gallery Plains, area index 52, ID 103, created by Aloe_vera - { - // 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: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ "....abc...." - /* 1 */ ".ddddddddd." - /* 2 */ ".ddddddddd." - /* 3 */ ".ddddddddd." - /* 4 */ ".ddddddddd." - /* 5 */ ".ddddddddd." - /* 6 */ ".ddddddddd." - /* 7 */ ".ddddddddd." - /* 8 */ "..........." - - // Level 1 - /* 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 2 - /* 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 3 - /* 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 4 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "jjjjjjjjjjj" - /* 2 */ "kfffffffffk" - /* 3 */ ".f.......f." - /* 4 */ ".f.......f." - /* 5 */ ".f.......f." - /* 6 */ "offfffffffo" - /* 7 */ "ppppppppppp" - /* 8 */ "..........." - - // Level 5 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "jjjjjjjjjjj" - /* 3 */ "kfffffffffk" - /* 4 */ ".f.......f." - /* 5 */ "offfffffffo" - /* 6 */ "ppppppppppp" - /* 7 */ "..........." - /* 8 */ "..........." - - // Level 6 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "..........." - /* 3 */ "jjjjjjjjjjj" - /* 4 */ "fffffffffff" - /* 5 */ "ppppppppppp" - /* 6 */ "..........." - /* 7 */ "..........." - /* 8 */ "...........", - - // Connectors: - "-1: 5, 0, 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, - }, // PlainsVillage_103 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_105: - // The data has been exported from the gallery Plains, area index 54, ID 105, created by Aloe_vera - { - // Size: - 7, 6, 9, // SizeX = 7, SizeY = 6, SizeZ = 9 - - // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 6, 5, 8, // MaxX, MaxY, MaxZ - - // Block definitions: - ".: 0: 0\n" /* air */ - "a:170: 0\n" /* haybale */ - "b: 67: 0\n" /* stairs */ - "c: 67: 2\n" /* stairs */ - "d: 67: 1\n" /* stairs */ - "e: 4: 0\n" /* cobblestone */ - "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 */ "abcccd." - /* 1 */ ".eeeee." - /* 2 */ ".eeeee." - /* 3 */ ".eeeee." - /* 4 */ ".eeeee." - /* 5 */ ".eeeee." - /* 6 */ ".eeeee." - /* 7 */ ".eeeee." - /* 8 */ "......." - - // Level 1 - /* z\x* 0123456 */ - /* 0 */ "......." - /* 1 */ ".f..af." - /* 2 */ ".g...g." - /* 3 */ ".ga.hg." - /* 4 */ ".fihif." - /* 5 */ ".gaaag." - /* 6 */ ".gijag." - /* 7 */ ".fgfgf." - /* 8 */ "......." - - // Level 2 - /* z\x* 0123456 */ - /* 0 */ ".k...k." - /* 1 */ ".f...f." - /* 2 */ ".g...g." - /* 3 */ ".g...g." - /* 4 */ ".fh..f." - /* 5 */ ".ghiag." - /* 6 */ ".ghiig." - /* 7 */ ".fgfgf." - /* 8 */ "......." - - // Level 3 - /* z\x* 0123456 */ - /* 0 */ "ln...op" - /* 1 */ "lgggggp" - /* 2 */ "lg...gp" - /* 3 */ "lg...gp" - /* 4 */ "lg...gp" - /* 5 */ "lgaa.gp" - /* 6 */ "lgiaigp" - /* 7 */ "lgggggp" - /* 8 */ "ln...op" - - // Level 4 - /* 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 5 - /* z\x* 0123456 */ - /* 0 */ "..lgp.." - /* 1 */ "..lgp.." - /* 2 */ "..lgp.." - /* 3 */ "..lgp.." - /* 4 */ "..lgp.." - /* 5 */ "..lgp.." - /* 6 */ "..lgp.." - /* 7 */ "..lgp.." - /* 8 */ "..lgp..", - - // Connectors: - "-1: 3, 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, - }, // PlainsVillage_105 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_106: - // The data has been exported from the gallery Plains, area index 55, ID 106, created by Aloe_vera - { - // 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: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ + "n:102: 0\n" /* glasspane */ + "o: 64:12\n" /* wooddoorblock */ + "p: 50: 3\n" /* torch */ + "q: 72: 0\n" /* woodplate */ + "r: 50: 4\n" /* torch */ "s: 53: 7\n" /* woodstairs */ - "t: 53: 6\n" /* woodstairs */ - "u: 53: 3\n" /* woodstairs */, + "t: 47: 0\n" /* bookshelf */ + "u: 50: 1\n" /* torch */ + "v: 50: 2\n" /* torch */ + "w: 53: 6\n" /* woodstairs */ + "x: 5: 0\n" /* wood */, // Block data: // Level 0 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ ".abbbbbbbbbbbc." - /* 1 */ ".ddddddddddddd." - /* 2 */ ".deeeeeeeeeeed." - /* 3 */ ".deeeeeeeeeeed." - /* 4 */ ".deeeeeeeeeeed." - /* 5 */ ".deeeeeeeeeeed." - /* 6 */ ".deeeeeeeeeeed." - /* 7 */ ".ddddddddddddd." - /* 8 */ "..............." + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "aaaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaaa" // Level 1 - /* 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 */ "..............." + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "bbbbbbbaaabb" + /* 1 */ "baaaaaaaaaab" + /* 2 */ "baaaaaaaaaab" + /* 3 */ "baaaaaaaaaab" + /* 4 */ "baaaaaaaaaab" + /* 5 */ "baaaaaaaaaab" + /* 6 */ "bbbbbbbbbbbb" // Level 2 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "..............." - /* 1 */ ".f...i...i...f." - /* 2 */ "..............." - /* 3 */ "..............." - /* 4 */ "..............." - /* 5 */ "..............." - /* 6 */ "..............." - /* 7 */ ".f...i...i...f." - /* 8 */ "..............." + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ ".......cde.." + /* 1 */ ".ffffffffff." + /* 2 */ ".ffffffffff." + /* 3 */ ".ffffffffff." + /* 4 */ ".ffffffffff." + /* 5 */ ".ffffffffff." + /* 6 */ "............" // Level 3 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "..............." - /* 1 */ ".fp.qip.qip.qf." - /* 2 */ "..............." - /* 3 */ "..............." - /* 4 */ "..............." - /* 5 */ "..............." - /* 6 */ "..............." - /* 7 */ ".f...i...i...f." - /* 8 */ "..............." + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".fffffffgff." + /* 2 */ ".fh.ijk...f." + /* 3 */ ".fj.......f." + /* 4 */ ".fl.ijkijkf." + /* 5 */ ".ffffffffff." + /* 6 */ "............" // Level 4 - /* 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" + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".fnnfnnfoff." + /* 2 */ ".n..pq.p.pn." + /* 3 */ ".nq.......n." + /* 4 */ ".n..rq.rq.n." + /* 5 */ ".fnnfnnfnnf." + /* 6 */ "............" // Level 5 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "..............." - /* 1 */ "rrrrrrrrrrrrrrr" - /* 2 */ "siiiiiiiiiiiiis" - /* 3 */ ".i...........i." - /* 4 */ ".i...........i." - /* 5 */ ".i...........i." - /* 6 */ "tiiiiiiiiiiiiit" - /* 7 */ "uuuuuuuuuuuuuuu" - /* 8 */ "..............." + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "llllllllllll" + /* 1 */ "sffffffffffs" + /* 2 */ ".fttttttttf." + /* 3 */ ".fu......vf." + /* 4 */ ".fttttttttf." + /* 5 */ "wffffffffffw" + /* 6 */ "hhhhhhhhhhhh" // Level 6 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "..............." - /* 1 */ "..............." - /* 2 */ "rrrrrrrrrrrrrrr" - /* 3 */ "siiiiiiiiiiiiis" - /* 4 */ ".i...........i." - /* 5 */ "tiiiiiiiiiiiiit" - /* 6 */ "uuuuuuuuuuuuuuu" - /* 7 */ "..............." - /* 8 */ "..............." + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "llllllllllll" + /* 2 */ "sxxxxxxxxxxs" + /* 3 */ ".xxxxxxxxxx." + /* 4 */ "wxxxxxxxxxxw" + /* 5 */ "hhhhhhhhhhhh" + /* 6 */ "............" // Level 7 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "..............." - /* 1 */ "..............." - /* 2 */ "..............." - /* 3 */ "rrrrrrrrrrrrrrr" - /* 4 */ "iiiiiiiiiiiiiii" - /* 5 */ "uuuuuuuuuuuuuuu" - /* 6 */ "..............." - /* 7 */ "..............." - /* 8 */ "...............", + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "llllllllllll" + /* 3 */ "xxxxxxxxxxxx" + /* 4 */ "hhhhhhhhhhhh" + /* 5 */ "............" + /* 6 */ "............", // Connectors: - "-1: 7, 0, 0: 2\n" /* Type -1, direction Z- */, + "-1: 8, 2, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -744,303 +274,12 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, - }, // PlainsVillage_106 + }, // CobbleHouse10x5Library /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_109: - // The data has been exported from the gallery Plains, area index 58, ID 109, created by Aloe_vera - { - // Size: - 7, 14, 13, // SizeX = 7, SizeY = 14, SizeZ = 13 - - // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 6, 13, 12, // MaxX, MaxY, MaxZ - - // Block definitions: - ".: 0: 0\n" /* air */ - "A: 85: 0\n" /* fence */ - "B:126: 8\n" /* woodenslab */ - "a: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ "..abc.." - /* 1 */ ".ddddd." - /* 2 */ ".ddddd." - /* 3 */ ".ddddd." - /* 4 */ ".ddddd." - /* 5 */ ".ddddd." - /* 6 */ ".ddddd." - /* 7 */ ".ddddd." - /* 8 */ ".ddddd." - /* 9 */ ".ddddd." - /* 10 */ ".ddddd." - /* 11 */ ".ddddd." - /* 12 */ "......." - - // Level 1 - /* 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 2 - /* 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 3 - /* 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 */ "sefffft" - /* 12 */ "su...vt" - - // Level 4 - /* 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 5 - /* 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 6 - /* 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 7 - /* 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 8 - /* z\x* 0123456 */ - /* 0 */ "......." - /* 1 */ ".ewwwe." - /* 2 */ ".xffhx." - /* 3 */ ".xfffx." - /* 4 */ ".xfffx." - /* 5 */ ".ewwwe." - /* 6 */ "......." - /* 7 */ "......." - /* 8 */ "......." - /* 9 */ "......." - /* 10 */ "......." - /* 11 */ "......." - /* 12 */ "......." - - // Level 9 - /* 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 10 - /* z\x* 0123456 */ - /* 0 */ "......." - /* 1 */ ".e...e." - /* 2 */ "......." - /* 3 */ "......." - /* 4 */ "......." - /* 5 */ ".e...e." - /* 6 */ "......." - /* 7 */ "......." - /* 8 */ "......." - /* 9 */ "......." - /* 10 */ "......." - /* 11 */ "......." - /* 12 */ "......." - - // Level 11 - /* z\x* 0123456 */ - /* 0 */ "su...vt" - /* 1 */ "sefffet" - /* 2 */ "sfBBBft" - /* 3 */ "sfBBBft" - /* 4 */ "sfBBBft" - /* 5 */ "sffffft" - /* 6 */ "su...vt" - /* 7 */ "......." - /* 8 */ "......." - /* 9 */ "......." - /* 10 */ "......." - /* 11 */ "......." - /* 12 */ "......." - - // Level 12 - /* 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 13 - /* 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, 0, 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, - }, // PlainsVillage_109 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_20: + // DoublePlantBed: // The data has been exported from the gallery Plains, area index 5, ID 20, created by tonibm1999 { // Size: @@ -1106,139 +345,202 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, - }, // PlainsVillage_20 + }, // DoublePlantBed /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_26: - // The data has been exported from the gallery Plains, area index 9, ID 26, created by Aloe_vera + // Forge: + // The data has been exported from the gallery Plains, area index 51, ID 102, created by Aloe_vera { // Size: - 10, 6, 11, // SizeX = 10, SizeY = 6, SizeZ = 11 + 12, 10, 11, // SizeX = 12, SizeY = 10, SizeZ = 11 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 9, 5, 10, // MaxX, MaxY, MaxZ + 11, 9, 10, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 4: 0\n" /* cobblestone */ - "b: 5: 0\n" /* wood */ - "c: 2: 0\n" /* grass */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ "d: 67: 2\n" /* stairs */ - "e: 43: 0\n" /* doubleslab */ - "f: 67: 0\n" /* stairs */ - "g: 67: 3\n" /* stairs */ - "h: 17: 0\n" /* tree */ - "i: 53: 1\n" /* woodstairs */ - "j: 85: 0\n" /* fence */ - "k: 53: 0\n" /* woodstairs */ - "l: 64: 6\n" /* wooddoorblock */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 6\n" /* wooddoorblock */ + "j: 10: 0\n" /* lava */ + "k: 54: 2\n" /* chest */ + "l: 61: 2\n" /* furnace */ "m: 19: 0\n" /* sponge */ - "n: 64: 0\n" /* wooddoorblock */ - "o:102: 0\n" /* glasspane */ - "p: 72: 0\n" /* woodplate */ - "q: 64:12\n" /* wooddoorblock */ - "r: 64: 8\n" /* wooddoorblock */ - "s: 53: 5\n" /* woodstairs */ - "t: 53: 4\n" /* woodstairs */ + "n:102: 0\n" /* glasspane */ + "o: 64:12\n" /* wooddoorblock */ + "p:139: 0\n" /* cobblestonewall */ + "q:101: 0\n" /* ironbars */ + "r: 53: 2\n" /* woodstairs */ + "s: 53: 7\n" /* woodstairs */ + "t: 50: 2\n" /* torch */ "u: 50: 1\n" /* torch */ - "v: 50: 2\n" /* torch */, + "v: 53: 6\n" /* woodstairs */ + "w: 53: 3\n" /* woodstairs */ + "x: 43: 0\n" /* doubleslab */ + "y: 44: 0\n" /* step */, // Block data: // Level 0 - /* z\x* */ - /* * 0123456789 */ - /* 0 */ "......mmmm" - /* 1 */ ".aaaaammmm" - /* 2 */ ".abbbammmm" - /* 3 */ ".abbbacccc" - /* 4 */ "daeeeacccc" - /* 5 */ "faeeeecccc" - /* 6 */ "gaeeeacccc" - /* 7 */ ".aeeeacccc" - /* 8 */ ".aeeeacccc" - /* 9 */ ".aaaaammmm" - /* 10 */ "......mmmm" + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "aaaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaaa" + /* 7 */ "aaaaaaaaaaaa" + /* 8 */ "aaaaaaaaaaaa" + /* 9 */ "aaaaaaaaaaaa" + /* 10 */ "aaaaaaaaaaaa" // Level 1 - /* z\x* */ - /* * 0123456789 */ - /* 0 */ "......mmmm" - /* 1 */ ".hbbbhmmmm" - /* 2 */ ".bijkbmmmm" - /* 3 */ ".b...bjjjj" - /* 4 */ ".b...b...j" - /* 5 */ ".l...n...j" - /* 6 */ ".b...b...j" - /* 7 */ ".bee.b...j" - /* 8 */ ".b...bjjjj" - /* 9 */ ".hbbbhmmmm" - /* 10 */ "......mmmm" + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "bbbbbaaaaabb" + /* 1 */ "baaaaaaaaabb" + /* 2 */ "baaaaaaaaabb" + /* 3 */ "baaaaaaaaaaa" + /* 4 */ "baaaaaaaaaaa" + /* 5 */ "baaaaaaaaaaa" + /* 6 */ "baaaaaaaaaaa" + /* 7 */ "baaaaaaaaaaa" + /* 8 */ "baaaaabbbbbb" + /* 9 */ "baaaaabbbbbb" + /* 10 */ "bbbbbbbbbbbb" // Level 2 - /* z\x* */ - /* * 0123456789 */ - /* 0 */ "......mmmm" - /* 1 */ ".hooohmmmm" - /* 2 */ ".o.p.ommmm" - /* 3 */ ".o...o...." - /* 4 */ ".b...b...." - /* 5 */ ".q...r...." - /* 6 */ ".b...b...." - /* 7 */ ".o...o...." - /* 8 */ ".o...o...." - /* 9 */ ".hooohmmmm" - /* 10 */ "......mmmm" + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ ".....cddde.." + /* 1 */ ".ffffffffe.." + /* 2 */ ".ffffffffe.." + /* 3 */ ".fffffffffff" + /* 4 */ ".fffffffffff" + /* 5 */ ".fffffffffff" + /* 6 */ ".fffffffffff" + /* 7 */ ".fffffffffff" + /* 8 */ ".fffff.mmmmm" + /* 9 */ ".fffff.mmmmm" + /* 10 */ ".......mmmmm" // Level 3 - /* z\x* */ - /* * 0123456789 */ - /* 0 */ "ks...timmm" - /* 1 */ "khbbbhimmm" - /* 2 */ "kb...bimmm" - /* 3 */ "kb...bi..." - /* 4 */ "kbu.vbi..." - /* 5 */ "kb...bi..." - /* 6 */ "kbu.vbi..." - /* 7 */ "kb...bi..." - /* 8 */ "kb...bi..." - /* 9 */ "khbbbhimmm" - /* 10 */ "ks...timmm" + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".ghhhg......" + /* 2 */ ".h...i......" + /* 3 */ ".h...gf..fff" + /* 4 */ ".h...h...fjf" + /* 5 */ ".h...h...fjf" + /* 6 */ ".h...hkllfjf" + /* 7 */ ".h...gffffff" + /* 8 */ ".h...h.mmmmm" + /* 9 */ ".ghhhg.mmmmm" + /* 10 */ ".......mmmmm" // Level 4 - /* z\x* */ - /* * 0123456789 */ - /* 0 */ "mks.timmmm" - /* 1 */ "mkbbbimmmm" - /* 2 */ "mkb.bimmmm" - /* 3 */ "mkb.bim..." - /* 4 */ "mkb.bim..." - /* 5 */ "mkb.bim..." - /* 6 */ "mkb.bim..." - /* 7 */ "mkb.bim..." - /* 8 */ "mkb.bim..." - /* 9 */ "mkbbbimmmm" - /* 10 */ "mks.timmmm" + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".gnnng......" + /* 2 */ ".n...o......" + /* 3 */ ".n...gp..p.f" + /* 4 */ ".n...n.....q" + /* 5 */ ".h...n.....q" + /* 6 */ ".n...n.....q" + /* 7 */ ".n...gfqqqqf" + /* 8 */ ".n...h.mmmmm" + /* 9 */ ".gnnng.mmmmm" + /* 10 */ ".......mmmmm" // Level 5 - /* z\x* */ - /* * 0123456789 */ - /* 0 */ "mmkbimmmmm" - /* 1 */ "mmkbimmmmm" - /* 2 */ "mmkbimmmmm" - /* 3 */ "mmkbimm..." - /* 4 */ "mmkbimm..." - /* 5 */ "mmkbimm..." - /* 6 */ "mmkbimm..." - /* 7 */ "mmkbimm..." - /* 8 */ "mmkbimm..." - /* 9 */ "mmkbimmmmm" - /* 10 */ "mmkbimmmmm", + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "rrrrrrr....." + /* 1 */ "shhhhhs....." + /* 2 */ ".h...h......" + /* 3 */ ".h..thf..fqf" + /* 4 */ ".h...h...q.f" + /* 5 */ ".h...h...q.f" + /* 6 */ ".hu..h...q.f" + /* 7 */ ".h...hffffff" + /* 8 */ ".h...h.mmmmm" + /* 9 */ "vhhhhhvmmmmm" + /* 10 */ "wwwwwwwmmmmm" + + // Level 6 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "rrrrrrr....." + /* 2 */ "shhhhhs....." + /* 3 */ ".h...hxxxxxx" + /* 4 */ ".h...hxyyyyx" + /* 5 */ ".h...hxyyyyx" + /* 6 */ ".h...hxyyyyx" + /* 7 */ ".h...hxxxxxx" + /* 8 */ "vhhhhhvmmmmm" + /* 9 */ "wwwwwwwmmmmm" + /* 10 */ ".......mmmmm" + + // Level 7 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "rrrrrrr....." + /* 3 */ "shhhhhs....." + /* 4 */ ".h...h......" + /* 5 */ ".h...h......" + /* 6 */ ".h...h......" + /* 7 */ "vhhhhhv....." + /* 8 */ "wwwwwwwmmmmm" + /* 9 */ ".......mmmmm" + /* 10 */ ".......mmmmm" + + // Level 8 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "............" + /* 3 */ "rrrrrrr....." + /* 4 */ "shhhhhs....." + /* 5 */ ".h...h......" + /* 6 */ "vhhhhhv....." + /* 7 */ "wwwwwww....." + /* 8 */ ".......mmmmm" + /* 9 */ ".......mmmmm" + /* 10 */ ".......mmmmm" + + // Level 9 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "............" + /* 3 */ "............" + /* 4 */ "rrrrrrr....." + /* 5 */ "hhhhhhh....." + /* 6 */ "wwwwwww....." + /* 7 */ "............" + /* 8 */ ".......mmmmm" + /* 9 */ ".......mmmmm" + /* 10 */ ".......mmmmm", // Connectors: - "-1: 1, 0, 5: 4\n" /* Type -1, direction X- */, + "-1: 7, 2, -1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1257,12 +559,2333 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, - }, // PlainsVillage_26 + }, // Forge /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_4: + // SinglePlantBed: + // The data has been exported from the gallery Plains, area index 17, ID 60, created by Aloe_vera + { + // Size: + 10, 3, 7, // SizeX = 10, SizeY = 3, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 9, 2, 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 */ "..........", + + // 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, + }, // SinglePlantBed + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenChurchMid: + // The data has been exported from the gallery Plains, area index 58, ID 109, created by Aloe_vera + { + // Size: + 7, 16, 13, // SizeX = 7, SizeY = 16, SizeZ = 13 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 15, 12, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "A: 54: 2\n" /* chest */ + "B: 50: 4\n" /* torch */ + "C: 85: 0\n" /* fence */ + "D:126: 8\n" /* woodenslab */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 7\n" /* wooddoorblock */ + "j: 65: 3\n" /* ladder */ + "k: 53: 3\n" /* woodstairs */ + "l: 53: 7\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 64:12\n" /* wooddoorblock */ + "o:102: 0\n" /* glasspane */ + "p: 50: 1\n" /* torch */ + "q: 50: 2\n" /* torch */ + "r:171:14\n" /* carpet */ + "s: 50: 3\n" /* torch */ + "t: 53: 2\n" /* woodstairs */ + "u: 53: 0\n" /* woodstairs */ + "v: 53: 1\n" /* woodstairs */ + "w: 53: 5\n" /* woodstairs */ + "x: 53: 4\n" /* woodstairs */ + "y: 17: 4\n" /* tree */ + "z: 17: 8\n" /* tree */, + + // Block data: + // Level 0 + /* z\x* 0123456 */ + /* 0 */ "aaaaaaa" + /* 1 */ "aaaaaaa" + /* 2 */ "aaaaaaa" + /* 3 */ "aaaaaaa" + /* 4 */ "aaaaaaa" + /* 5 */ "aaaaaaa" + /* 6 */ "aaaaaaa" + /* 7 */ "aaaaaaa" + /* 8 */ "aaaaaaa" + /* 9 */ "aaaaaaa" + /* 10 */ "aaaaaaa" + /* 11 */ "aaaaaaa" + /* 12 */ "aaaaaaa" + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "bbaaabb" + /* 1 */ "baaaaab" + /* 2 */ "baaaaab" + /* 3 */ "baaaaab" + /* 4 */ "baaaaab" + /* 5 */ "baaaaab" + /* 6 */ "baaaaab" + /* 7 */ "baaaaab" + /* 8 */ "baaaaab" + /* 9 */ "baaaaab" + /* 10 */ "baaaaab" + /* 11 */ "baaaaab" + /* 12 */ "bbbbbbb" + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "..cde.." + /* 1 */ ".fffff." + /* 2 */ ".fffff." + /* 3 */ ".fffff." + /* 4 */ ".fffff." + /* 5 */ ".fffff." + /* 6 */ ".fffff." + /* 7 */ ".fffff." + /* 8 */ ".fffff." + /* 9 */ ".fffff." + /* 10 */ ".fffff." + /* 11 */ ".fffff." + /* 12 */ "......." + + // Level 3 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ghihg." + /* 2 */ ".h..jh." + /* 3 */ ".h...h." + /* 4 */ ".h...h." + /* 5 */ ".gk.kg." + /* 6 */ ".h...h." + /* 7 */ ".hk.kh." + /* 8 */ ".h...h." + /* 9 */ ".h.l.h." + /* 10 */ ".h...h." + /* 11 */ ".ghhhg." + /* 12 */ "......." + + // Level 4 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ghnhg." + /* 2 */ ".o..jo." + /* 3 */ ".o...o." + /* 4 */ ".o...o." + /* 5 */ ".g...g." + /* 6 */ ".o...o." + /* 7 */ ".o...o." + /* 8 */ ".hp.qh." + /* 9 */ ".o.r.o." + /* 10 */ ".o...o." + /* 11 */ ".gooog." + /* 12 */ "......." + + // Level 5 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ghhhg." + /* 2 */ ".h.sjh." + /* 3 */ ".h...h." + /* 4 */ ".h...h." + /* 5 */ "tg...gt" + /* 6 */ "uh...hv" + /* 7 */ "uh...hv" + /* 8 */ "uh...hv" + /* 9 */ "uh...hv" + /* 10 */ "uh...hv" + /* 11 */ "ughhhhv" + /* 12 */ "uw...xv" + + // Level 6 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".gyyyg." + /* 2 */ ".zhhjz." + /* 3 */ ".zhhhz." + /* 4 */ ".zhhhz." + /* 5 */ ".gyyyg." + /* 6 */ ".uh.hv." + /* 7 */ ".uh.hv." + /* 8 */ ".uh.hv." + /* 9 */ ".uh.hv." + /* 10 */ ".uh.hv." + /* 11 */ ".uhhhv." + /* 12 */ ".uw.xv." + + // Level 7 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ghohg." + /* 2 */ ".h..jh." + /* 3 */ ".h...h." + /* 4 */ ".h.A.h." + /* 5 */ ".ghhhg." + /* 6 */ "..uhv.." + /* 7 */ "..uhv.." + /* 8 */ "..uhv.." + /* 9 */ "..uhv.." + /* 10 */ "..uhv.." + /* 11 */ "..uhv.." + /* 12 */ "..uhv.." + + // Level 8 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ghohg." + /* 2 */ ".h..jh." + /* 3 */ ".o...o." + /* 4 */ ".h...h." + /* 5 */ ".ghhhg." + /* 6 */ "......." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 9 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ghohg." + /* 2 */ ".h..jh." + /* 3 */ ".h...h." + /* 4 */ ".h.B.h." + /* 5 */ ".ghhhg." + /* 6 */ "......." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 10 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".gyyyg." + /* 2 */ ".zhhjz." + /* 3 */ ".zhhhz." + /* 4 */ ".zhhhz." + /* 5 */ ".gyyyg." + /* 6 */ "......." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 11 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".gCCCg." + /* 2 */ ".C...C." + /* 3 */ ".C...C." + /* 4 */ ".C...C." + /* 5 */ ".gCCCg." + /* 6 */ "......." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 12 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".g...g." + /* 2 */ "......." + /* 3 */ "......." + /* 4 */ "......." + /* 5 */ ".g...g." + /* 6 */ "......." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 13 + /* z\x* 0123456 */ + /* 0 */ "uw...xv" + /* 1 */ "ughhhgv" + /* 2 */ "uhDDDhv" + /* 3 */ "uhDDDhv" + /* 4 */ "uhDDDhv" + /* 5 */ "uhhhhhv" + /* 6 */ "uw...xv" + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 14 + /* z\x* 0123456 */ + /* 0 */ ".uw.xv." + /* 1 */ ".uhhhv." + /* 2 */ ".uhhhv." + /* 3 */ ".uhhhv." + /* 4 */ ".uhhhv." + /* 5 */ ".uhhhv." + /* 6 */ ".uw.xv." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ "......." + + // Level 15 + /* z\x* 0123456 */ + /* 0 */ "..uhv.." + /* 1 */ "..uhv.." + /* 2 */ "..uhv.." + /* 3 */ "..uhv.." + /* 4 */ "..uhv.." + /* 5 */ "..uhv.." + /* 6 */ "..uhv.." + /* 7 */ "......." + /* 8 */ "......." + /* 9 */ "......." + /* 10 */ "......." + /* 11 */ "......." + /* 12 */ ".......", + + // Connectors: + "-1: 3, 2, 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, + }, // WoodenChurchMid + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenGranary: + // The data has been exported from the gallery Plains, area index 54, ID 105, created by Aloe_vera + { + // Size: + 7, 8, 9, // SizeX = 7, SizeY = 8, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 7, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c:170: 0\n" /* haybale */ + "d: 67: 0\n" /* stairs */ + "e: 67: 2\n" /* stairs */ + "f: 67: 1\n" /* stairs */ + "g: 4: 0\n" /* cobblestone */ + "h: 17: 0\n" /* tree */ + "i: 5: 0\n" /* wood */ + "j:170: 4\n" /* haybale */ + "k:170: 8\n" /* haybale */ + "l: 54: 2\n" /* chest */ + "m: 19: 0\n" /* sponge */ + "n: 50: 4\n" /* torch */ + "o: 53: 0\n" /* woodstairs */ + "p: 53: 5\n" /* woodstairs */ + "q: 53: 4\n" /* woodstairs */ + "r: 53: 1\n" /* woodstairs */, + + // Block data: + // Level 0 + /* z\x* 0123456 */ + /* 0 */ "aaaaaaa" + /* 1 */ "aaaaaaa" + /* 2 */ "aaaaaaa" + /* 3 */ "aaaaaaa" + /* 4 */ "aaaaaaa" + /* 5 */ "aaaaaaa" + /* 6 */ "aaaaaaa" + /* 7 */ "aaaaaaa" + /* 8 */ "aaaaaaa" + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "aaaaaab" + /* 1 */ "baaaaab" + /* 2 */ "baaaaab" + /* 3 */ "baaaaab" + /* 4 */ "baaaaab" + /* 5 */ "baaaaab" + /* 6 */ "baaaaab" + /* 7 */ "baaaaab" + /* 8 */ "bbbbbbb" + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "cdeeef." + /* 1 */ ".ggggg." + /* 2 */ ".ggggg." + /* 3 */ ".ggggg." + /* 4 */ ".ggggg." + /* 5 */ ".ggggg." + /* 6 */ ".ggggg." + /* 7 */ ".ggggg." + /* 8 */ "......." + + // Level 3 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".h..ch." + /* 2 */ ".i...i." + /* 3 */ ".ic.ji." + /* 4 */ ".hkjkh." + /* 5 */ ".iccci." + /* 6 */ ".iklci." + /* 7 */ ".hihih." + /* 8 */ "......." + + // Level 4 + /* z\x* 0123456 */ + /* 0 */ ".n...n." + /* 1 */ ".h...h." + /* 2 */ ".i...i." + /* 3 */ ".i...i." + /* 4 */ ".hj..h." + /* 5 */ ".ijkci." + /* 6 */ ".ijkki." + /* 7 */ ".hihih." + /* 8 */ "......." + + // Level 5 + /* z\x* 0123456 */ + /* 0 */ "op...qr" + /* 1 */ "oiiiiir" + /* 2 */ "oi...ir" + /* 3 */ "oi...ir" + /* 4 */ "oi...ir" + /* 5 */ "oicc.ir" + /* 6 */ "oikckir" + /* 7 */ "oiiiiir" + /* 8 */ "op...qr" + + // Level 6 + /* z\x* 0123456 */ + /* 0 */ ".op.qr." + /* 1 */ ".oiiir." + /* 2 */ ".oi.ir." + /* 3 */ ".oi.ir." + /* 4 */ ".oi.ir." + /* 5 */ ".oi.ir." + /* 6 */ ".oi.ir." + /* 7 */ ".oiiir." + /* 8 */ ".op.qr." + + // Level 7 + /* z\x* 0123456 */ + /* 0 */ "..oir.." + /* 1 */ "..oir.." + /* 2 */ "..oir.." + /* 3 */ "..oir.." + /* 4 */ "..oir.." + /* 5 */ "..oir.." + /* 6 */ "..oir.." + /* 7 */ "..oir.." + /* 8 */ "..oir..", + + // Connectors: + "-1: 3, 2, -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, + }, // WoodenGranary + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouse10x7Library: + // The data has been exported from the gallery Plains, area index 47, ID 98, created by Aloe_vera + { + // Size: + 12, 9, 9, // SizeX = 12, SizeY = 9, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 11, 8, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 7\n" /* wooddoorblock */ + "j: 64: 5\n" /* wooddoorblock */ + "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:102: 0\n" /* glasspane */ + "r: 64:12\n" /* wooddoorblock */ + "s: 50: 3\n" /* torch */ + "t: 72: 0\n" /* woodplate */ + "u: 53: 7\n" /* woodstairs */ + "v: 47: 0\n" /* bookshelf */ + "w: 50: 1\n" /* torch */ + "x: 50: 2\n" /* torch */ + "y: 53: 6\n" /* woodstairs */, + + // Block data: + // Level 0 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "aaaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaaa" + /* 7 */ "aaaaaaaaaaaa" + /* 8 */ "aaaaaaaaaaaa" + + // Level 1 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "bbbbaaaabbbb" + /* 1 */ "baaaaaaaaaab" + /* 2 */ "baaaaaaaaaab" + /* 3 */ "baaaaaaaaaab" + /* 4 */ "baaaaaaaaaab" + /* 5 */ "baaaaaaaaaab" + /* 6 */ "baaaaaaaaaab" + /* 7 */ "baaaaaaaaaab" + /* 8 */ "bbbbbbbbbbbb" + + // Level 2 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "....cdde...." + /* 1 */ ".ffffffffff." + /* 2 */ ".ffffffffff." + /* 3 */ ".ffffffffff." + /* 4 */ ".ffffffffff." + /* 5 */ ".ffffffffff." + /* 6 */ ".ffffffffff." + /* 7 */ ".ffffffffff." + /* 8 */ "............" + + // Level 3 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".ghhhijhhhg." + /* 2 */ ".h........h." + /* 3 */ ".hk......kh." + /* 4 */ ".hl......lh." + /* 5 */ ".hn......nh." + /* 6 */ ".h.olpolp.h." + /* 7 */ ".ghhhhhhhhg." + /* 8 */ "............" + + // Level 4 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".gqqhrrhqqg." + /* 2 */ ".q..s..s..q." + /* 3 */ ".q........q." + /* 4 */ ".ht......th." + /* 5 */ ".q........q." + /* 6 */ ".q..t..t..q." + /* 7 */ ".gqqhqqhqqg." + /* 8 */ "............" + + // Level 5 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "nnnnnnnnnnnn" + /* 1 */ "uhhhhhhhhhhu" + /* 2 */ ".hvvvvvvvvh." + /* 3 */ ".h........h." + /* 4 */ ".hw......xh." + /* 5 */ ".h........h." + /* 6 */ ".hvvvvvvvvh." + /* 7 */ "yhhhhhhhhhhy" + /* 8 */ "kkkkkkkkkkkk" + + // Level 6 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "nnnnnnnnnnnn" + /* 2 */ "uhhhhhhhhhhu" + /* 3 */ ".hvvvvvvvvh." + /* 4 */ ".h........h." + /* 5 */ ".hvvvvvvvvh." + /* 6 */ "yhhhhhhhhhhy" + /* 7 */ "kkkkkkkkkkkk" + /* 8 */ "............" + + // Level 7 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "nnnnnnnnnnnn" + /* 3 */ "uhhhhhhhhhhu" + /* 4 */ ".h........h." + /* 5 */ "yhhhhhhhhhhy" + /* 6 */ "kkkkkkkkkkkk" + /* 7 */ "............" + /* 8 */ "............" + + // Level 8 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ "............" + /* 2 */ "............" + /* 3 */ "nnnnnnnnnnnn" + /* 4 */ "hhhhhhhhhhhh" + /* 5 */ "kkkkkkkkkkkk" + /* 6 */ "............" + /* 7 */ "............" + /* 8 */ "............", + + // 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, + }, // WoodenHouse10x7Library + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouse5x5: + // The data has been exported from the gallery Plains, area index 49, ID 100, created by Aloe_vera + { + // Size: + 7, 8, 7, // SizeX = 7, SizeY = 8, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 7, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 7\n" /* wooddoorblock */ + "j: 64:12\n" /* wooddoorblock */ + "k:102: 0\n" /* glasspane */ + "l: 53: 2\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 53: 7\n" /* woodstairs */ + "o: 50: 3\n" /* torch */ + "p: 53: 6\n" /* woodstairs */ + "q: 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 */ "bbaaabb" + /* 1 */ "baaaaab" + /* 2 */ "baaaaab" + /* 3 */ "baaaaab" + /* 4 */ "baaaaab" + /* 5 */ "baaaaab" + /* 6 */ "bbbbbbb" + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "..cde.." + /* 1 */ ".fffff." + /* 2 */ ".fffff." + /* 3 */ ".fffff." + /* 4 */ ".fffff." + /* 5 */ ".fffff." + /* 6 */ "......." + + // Level 3 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ghihg." + /* 2 */ ".h...h." + /* 3 */ ".h...h." + /* 4 */ ".h...h." + /* 5 */ ".ghhhg." + /* 6 */ "......." + + // Level 4 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ghjhg." + /* 2 */ ".k...k." + /* 3 */ ".k...k." + /* 4 */ ".k...k." + /* 5 */ ".gkkkg." + /* 6 */ "......." + + // Level 5 + /* z\x* 0123456 */ + /* 0 */ "lllllll" + /* 1 */ "nhhhhhn" + /* 2 */ ".ho.oh." + /* 3 */ ".h...h." + /* 4 */ ".h...h." + /* 5 */ "phhhhhp" + /* 6 */ "qqqqqqq" + + // Level 6 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ "lllllll" + /* 2 */ "nhhhhhn" + /* 3 */ ".h...h." + /* 4 */ "phhhhhp" + /* 5 */ "qqqqqqq" + /* 6 */ "......." + + // Level 7 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ "......." + /* 2 */ "lllllll" + /* 3 */ "hhhhhhh" + /* 4 */ "qqqqqqq" + /* 5 */ "......." + /* 6 */ ".......", + + // Connectors: + "-1: 3, 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, + }, // WoodenHouse5x5 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouse7x5: + // The data has been exported from the gallery Plains, area index 40, ID 91, created by xoft + { + // Size: + 9, 8, 7, // SizeX = 9, SizeY = 8, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 8, 7, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 7\n" /* wooddoorblock */ + "j:102: 0\n" /* glasspane */ + "k: 64:12\n" /* wooddoorblock */ + "l: 53: 2\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 53: 7\n" /* woodstairs */ + "o: 50: 3\n" /* torch */ + "p: 53: 6\n" /* woodstairs */ + "q: 53: 3\n" /* woodstairs */, + + // Block data: + // Level 0 + /* z\x* 012345678 */ + /* 0 */ "aaaaaaaaa" + /* 1 */ "aaaaaaaaa" + /* 2 */ "aaaaaaaaa" + /* 3 */ "aaaaaaaaa" + /* 4 */ "aaaaaaaaa" + /* 5 */ "aaaaaaaaa" + /* 6 */ "aaaaaaaaa" + + // Level 1 + /* z\x* 012345678 */ + /* 0 */ "bbbaaabbb" + /* 1 */ "baaaaaaab" + /* 2 */ "baaaaaaab" + /* 3 */ "baaaaaaab" + /* 4 */ "baaaaaaab" + /* 5 */ "baaaaaaab" + /* 6 */ "bbbbbbbbb" + + // Level 2 + /* z\x* 012345678 */ + /* 0 */ "...cde..." + /* 1 */ ".fffffff." + /* 2 */ ".fffffff." + /* 3 */ ".fffffff." + /* 4 */ ".fffffff." + /* 5 */ ".fffffff." + /* 6 */ "........." + + // Level 3 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ ".ghhihhg." + /* 2 */ ".h.....h." + /* 3 */ ".h.....h." + /* 4 */ ".h.....h." + /* 5 */ ".ghhhhhg." + /* 6 */ "........." + + // Level 4 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ ".gjhkhjg." + /* 2 */ ".j.....j." + /* 3 */ ".j.....j." + /* 4 */ ".j.....j." + /* 5 */ ".gjjhjjg." + /* 6 */ "........." + + // Level 5 + /* z\x* 012345678 */ + /* 0 */ "lllllllll" + /* 1 */ "nghhhhhgn" + /* 2 */ ".h.o.o.h." + /* 3 */ ".h.....h." + /* 4 */ ".h.....h." + /* 5 */ "pghhhhhgp" + /* 6 */ "qqqqqqqqq" + + // Level 6 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "lllllllll" + /* 2 */ "nhhhhhhhn" + /* 3 */ ".h.....h." + /* 4 */ "phhhhhhhp" + /* 5 */ "qqqqqqqqq" + /* 6 */ "........." + + // Level 7 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "lllllllll" + /* 3 */ "hhhhhhhhh" + /* 4 */ "qqqqqqqqq" + /* 5 */ "........." + /* 6 */ ".........", + + // Connectors: + "-1: 4, 2, -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, + }, // WoodenHouse7x5 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouse9x5: + // The data has been exported from the gallery Plains, area index 41, ID 92, created by xoft + { + // Size: + 11, 8, 7, // SizeX = 11, SizeY = 8, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 7, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 7\n" /* wooddoorblock */ + "j:102: 0\n" /* glasspane */ + "k: 64:12\n" /* wooddoorblock */ + "l: 53: 2\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 53: 7\n" /* woodstairs */ + "o: 50: 3\n" /* torch */ + "p: 53: 6\n" /* woodstairs */ + "q: 53: 3\n" /* woodstairs */, + + // Block data: + // Level 0 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "aaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaa" + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "bbbbaaabbbb" + /* 1 */ "baaaaaaaaab" + /* 2 */ "baaaaaaaaab" + /* 3 */ "baaaaaaaaab" + /* 4 */ "baaaaaaaaab" + /* 5 */ "baaaaaaaaab" + /* 6 */ "bbbbbbbbbbb" + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "....cde...." + /* 1 */ ".fffffffff." + /* 2 */ ".fffffffff." + /* 3 */ ".fffffffff." + /* 4 */ ".fffffffff." + /* 5 */ ".fffffffff." + /* 6 */ "..........." + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".ghhhihhhg." + /* 2 */ ".h.......h." + /* 3 */ ".h.......h." + /* 4 */ ".h.......h." + /* 5 */ ".ghhhhhhhg." + /* 6 */ "..........." + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".gjjhkhjjg." + /* 2 */ ".j.......j." + /* 3 */ ".j.......j." + /* 4 */ ".j.......j." + /* 5 */ ".gjjjhjjjg." + /* 6 */ "..........." + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "lllllllllll" + /* 1 */ "nhhhhhhhhhn" + /* 2 */ ".h..o.o.hh." + /* 3 */ ".h......hh." + /* 4 */ ".h......hh." + /* 5 */ "phhhhhhhhhp" + /* 6 */ "qqqqqqqqqqq" + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "lllllllllll" + /* 2 */ "nhhhhhhhhhn" + /* 3 */ ".hhhhhhhhh." + /* 4 */ "phhhhhhhhhp" + /* 5 */ "qqqqqqqqqqq" + /* 6 */ "..........." + + // Level 7 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "lllllllllll" + /* 3 */ "hhhhhhhhhhh" + /* 4 */ "qqqqqqqqqqq" + /* 5 */ "..........." + /* 6 */ "...........", + + // Connectors: + "-1: 5, 2, -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, + }, // WoodenHouse9x5 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouse9x5: + // The data has been exported from the gallery Plains, area index 46, ID 97, created by Aloe_vera + { + // Size: + 11, 8, 7, // SizeX = 11, SizeY = 8, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 7, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 7\n" /* wooddoorblock */ + "j: 53: 3\n" /* woodstairs */ + "k: 85: 0\n" /* fence */ + "l: 53: 2\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 53: 1\n" /* woodstairs */ + "o: 53: 0\n" /* woodstairs */ + "p:102: 0\n" /* glasspane */ + "q: 64:12\n" /* wooddoorblock */ + "r: 50: 3\n" /* torch */ + "s: 72: 0\n" /* woodplate */ + "t: 53: 7\n" /* woodstairs */ + "u: 47: 0\n" /* bookshelf */ + "v: 50: 1\n" /* torch */ + "w: 50: 2\n" /* torch */ + "x: 53: 6\n" /* woodstairs */, + + // Block data: + // Level 0 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "aaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaa" + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "bbbbaaabbbb" + /* 1 */ "baaaaaaaaab" + /* 2 */ "baaaaaaaaab" + /* 3 */ "baaaaaaaaab" + /* 4 */ "baaaaaaaaab" + /* 5 */ "baaaaaaaaab" + /* 6 */ "bbbbbbbbbbb" + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "....cde...." + /* 1 */ ".fffffffff." + /* 2 */ ".fffffffff." + /* 3 */ ".fffffffff." + /* 4 */ ".fffffffff." + /* 5 */ ".fffffffff." + /* 6 */ "..........." + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".ghhhihhhg." + /* 2 */ ".hj.....jh." + /* 3 */ ".hk.....kh." + /* 4 */ ".hl.nko.lh." + /* 5 */ ".ghhhhhhhg." + /* 6 */ "..........." + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".gpphqhppg." + /* 2 */ ".p..r.r..p." + /* 3 */ ".ps.....sp." + /* 4 */ ".p...s...p." + /* 5 */ ".gppphpppg." + /* 6 */ "..........." + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "lllllllllll" + /* 1 */ "thhhhhhhhht" + /* 2 */ ".huuuuuuuh." + /* 3 */ ".hv.....wh." + /* 4 */ ".huuuuuuuh." + /* 5 */ "xhhhhhhhhhx" + /* 6 */ "jjjjjjjjjjj" + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "lllllllllll" + /* 2 */ "thhhhhhhhht" + /* 3 */ ".h.......h." + /* 4 */ "xhhhhhhhhhx" + /* 5 */ "jjjjjjjjjjj" + /* 6 */ "..........." + + // Level 7 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "lllllllllll" + /* 3 */ "hhhhhhhhhhh" + /* 4 */ "jjjjjjjjjjj" + /* 5 */ "..........." + /* 6 */ "...........", + + // 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, + }, // WoodenHouse9x5 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouse9x5Fence: + // The data has been exported from the gallery Plains, area index 9, ID 26, created by Aloe_vera + { + // Size: + 10, 8, 11, // SizeX = 10, SizeY = 8, SizeZ = 11 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 9, 7, 10, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 4: 0\n" /* cobblestone */ + "d: 5: 0\n" /* wood */ + "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: 0\n" /* wooddoorblock */ + "p:102: 0\n" /* glasspane */ + "q: 72: 0\n" /* woodplate */ + "r: 64:12\n" /* wooddoorblock */ + "s: 64: 8\n" /* wooddoorblock */ + "t: 53: 5\n" /* woodstairs */ + "u: 53: 4\n" /* woodstairs */ + "v: 50: 1\n" /* torch */ + "w: 50: 2\n" /* torch */, + + // Block data: + // Level 0 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "aaaaaaaaaa" + /* 1 */ "aaaaaaaaaa" + /* 2 */ "aaaaaaaaaa" + /* 3 */ "aaaaaaaaaa" + /* 4 */ "aaaaaaaaaa" + /* 5 */ "aaaaaaaaaa" + /* 6 */ "aaaaaaaaaa" + /* 7 */ "aaaaaaaaaa" + /* 8 */ "aaaaaaaaaa" + /* 9 */ "aaaaaaaaaa" + /* 10 */ "aaaaaaaaaa" + + // Level 1 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "bbbbbbbbbb" + /* 1 */ "baaaaabbbb" + /* 2 */ "baaaaabbbb" + /* 3 */ "baaaaaaaaa" + /* 4 */ "aaaaaaaaaa" + /* 5 */ "aaaaaaaaaa" + /* 6 */ "aaaaaaaaaa" + /* 7 */ "baaaaaaaaa" + /* 8 */ "baaaaaaaaa" + /* 9 */ "baaaaabbbb" + /* 10 */ "bbbbbbbbbb" + + // Level 2 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "......mmmm" + /* 1 */ ".cccccmmmm" + /* 2 */ ".cdddcmmmm" + /* 3 */ ".cdddcbbbb" + /* 4 */ "ecfffcbbbb" + /* 5 */ "gcffffbbbb" + /* 6 */ "hcfffcbbbb" + /* 7 */ ".cfffcbbbb" + /* 8 */ ".cfffcbbbb" + /* 9 */ ".cccccmmmm" + /* 10 */ "......mmmm" + + // Level 3 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "......mmmm" + /* 1 */ ".idddimmmm" + /* 2 */ ".djkldmmmm" + /* 3 */ ".d...dkkkk" + /* 4 */ ".d...d...k" + /* 5 */ ".n...o...k" + /* 6 */ ".d...d...k" + /* 7 */ ".dff.d...k" + /* 8 */ ".d...dkkkk" + /* 9 */ ".idddimmmm" + /* 10 */ "......mmmm" + + // Level 4 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "......mmmm" + /* 1 */ ".ipppimmmm" + /* 2 */ ".p.q.pmmmm" + /* 3 */ ".p...p...." + /* 4 */ ".d...d...." + /* 5 */ ".r...s...." + /* 6 */ ".d...d...." + /* 7 */ ".p...p...." + /* 8 */ ".p...p...." + /* 9 */ ".ipppimmmm" + /* 10 */ "......mmmm" + + // Level 5 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "lt...ujmmm" + /* 1 */ "lidddijmmm" + /* 2 */ "ld...djmmm" + /* 3 */ "ld...dj..." + /* 4 */ "ldv.wdj..." + /* 5 */ "ld...dj..." + /* 6 */ "ldv.wdj..." + /* 7 */ "ld...dj..." + /* 8 */ "ld...dj..." + /* 9 */ "lidddijmmm" + /* 10 */ "lt...ujmmm" + + // Level 6 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "mlt.ujmmmm" + /* 1 */ "mldddjmmmm" + /* 2 */ "mld.djmmmm" + /* 3 */ "mld.djm..." + /* 4 */ "mld.djm..." + /* 5 */ "mld.djm..." + /* 6 */ "mld.djm..." + /* 7 */ "mld.djm..." + /* 8 */ "mld.djm..." + /* 9 */ "mldddjmmmm" + /* 10 */ "mlt.ujmmmm" + + // Level 7 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "mmldjmmmmm" + /* 1 */ "mmldjmmmmm" + /* 2 */ "mmldjmmmmm" + /* 3 */ "mmldjmm..." + /* 4 */ "mmldjmm..." + /* 5 */ "mmldjmm..." + /* 6 */ "mmldjmm..." + /* 7 */ "mmldjmm..." + /* 8 */ "mmldjmm..." + /* 9 */ "mmldjmmmmm" + /* 10 */ "mmldjmmmmm", + + // Connectors: + "-1: 0, 2, 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, + }, // WoodenHouse9x5Fence + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouse9x7: + // The data has been exported from the gallery Plains, area index 52, ID 103, created by Aloe_vera + { + // Size: + 11, 9, 9, // SizeX = 11, SizeY = 9, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 8, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 7\n" /* wooddoorblock */ + "j:102: 0\n" /* glasspane */ + "k: 64:12\n" /* wooddoorblock */ + "l: 53: 2\n" /* woodstairs */ + "m: 19: 0\n" /* sponge */ + "n: 53: 7\n" /* woodstairs */ + "o: 50: 3\n" /* torch */ + "p: 50: 4\n" /* torch */ + "q: 53: 6\n" /* woodstairs */ + "r: 53: 3\n" /* woodstairs */, + + // Block data: + // Level 0 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "aaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaa" + /* 7 */ "aaaaaaaaaaa" + /* 8 */ "aaaaaaaaaaa" + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "bbbbaaabbbb" + /* 1 */ "baaaaaaaaab" + /* 2 */ "baaaaaaaaab" + /* 3 */ "baaaaaaaaab" + /* 4 */ "baaaaaaaaab" + /* 5 */ "baaaaaaaaab" + /* 6 */ "baaaaaaaaab" + /* 7 */ "baaaaaaaaab" + /* 8 */ "bbbbbbbbbbb" + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "....cde...." + /* 1 */ ".fffffffff." + /* 2 */ ".fffffffff." + /* 3 */ ".fffffffff." + /* 4 */ ".fffffffff." + /* 5 */ ".fffffffff." + /* 6 */ ".fffffffff." + /* 7 */ ".fffffffff." + /* 8 */ "..........." + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".ghhhihhhg." + /* 2 */ ".h.......h." + /* 3 */ ".h.......h." + /* 4 */ ".h.......h." + /* 5 */ ".h.......h." + /* 6 */ ".h.......h." + /* 7 */ ".ghhhhhhhg." + /* 8 */ "..........." + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".gjjhkhjjg." + /* 2 */ ".j.......j." + /* 3 */ ".j.......j." + /* 4 */ ".h.......h." + /* 5 */ ".j.......j." + /* 6 */ ".j.......j." + /* 7 */ ".gjjjhjjjg." + /* 8 */ "..........." + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "lllllllllll" + /* 1 */ "nhhhhhhhhhn" + /* 2 */ ".h..o.o..h." + /* 3 */ ".h.......h." + /* 4 */ ".h.......h." + /* 5 */ ".h.......h." + /* 6 */ ".h...p...h." + /* 7 */ "qhhhhhhhhhq" + /* 8 */ "rrrrrrrrrrr" + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "lllllllllll" + /* 2 */ "nhhhhhhhhhn" + /* 3 */ ".h.......h." + /* 4 */ ".h.......h." + /* 5 */ ".h.......h." + /* 6 */ "qhhhhhhhhhq" + /* 7 */ "rrrrrrrrrrr" + /* 8 */ "..........." + + // Level 7 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "lllllllllll" + /* 3 */ "nhhhhhhhhhn" + /* 4 */ ".h.......h." + /* 5 */ "qhhhhhhhhhq" + /* 6 */ "rrrrrrrrrrr" + /* 7 */ "..........." + /* 8 */ "..........." + + // Level 8 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ "lllllllllll" + /* 4 */ "hhhhhhhhhhh" + /* 5 */ "rrrrrrrrrrr" + /* 6 */ "..........." + /* 7 */ "..........." + /* 8 */ "...........", + + // 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, + }, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 10, 8, 12, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "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 */ "aaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaa" + /* 7 */ "aaaaaaaaaaa" + /* 8 */ "aaaaaaaaaaa" + /* 9 */ "aaaaaaaaaaa" + /* 10 */ "aaaaaaaaaaa" + /* 11 */ "aaaaaaaaaaa" + /* 12 */ "aaaaaaaaaaa" + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "bbbbaaabbbb" + /* 1 */ "baaaaaaaaab" + /* 2 */ "baaaaaaaaab" + /* 3 */ "baaaaaaaaab" + /* 4 */ "baaaaaaaaab" + /* 5 */ "baaaaaaaaab" + /* 6 */ "baaaaaaaaab" + /* 7 */ "baaaaaaaaab" + /* 8 */ "bbaaaaaaabb" + /* 9 */ "bbaaaaaaabb" + /* 10 */ "bbaaaaaaabb" + /* 11 */ "bbaaaaaaabb" + /* 12 */ "bbaaaaaaabb" + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "....cde...." + /* 1 */ ".fffffffff." + /* 2 */ ".fggggffff." + /* 3 */ ".fggggffff." + /* 4 */ ".fggggffff." + /* 5 */ ".fggggffff." + /* 6 */ ".fggggffff." + /* 7 */ ".fffffffff." + /* 8 */ "..bbbbbbb.." + /* 9 */ "mmbbbbbbbmm" + /* 10 */ "mmbbbbbbbmm" + /* 11 */ "mmbbbbbbbmm" + /* 12 */ "mmbbbbbbbmm" + + // 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 */ "mml.....lmm" + /* 10 */ "mml.....lmm" + /* 11 */ "mml.....lmm" + /* 12 */ "mmlllllllmm" + + // 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 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm" + + // 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 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm" + + // 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 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm" + + // Level 7 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "nnnnnnnnnnn" + /* 3 */ "riiiiiiiiir" + /* 4 */ ".i.......i." + /* 5 */ "uiiiiiiiiiu" + /* 6 */ "kkkkkkkkkkk" + /* 7 */ "..........." + /* 8 */ "..........." + /* 9 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm" + + // Level 8 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ "nnnnnnnnnnn" + /* 4 */ "iiiiiiiiiii" + /* 5 */ "kkkkkkkkkkk" + /* 6 */ "..........." + /* 7 */ "..........." + /* 8 */ "..........." + /* 9 */ "mm.......mm" + /* 10 */ "mm.......mm" + /* 11 */ "mm.......mm" + /* 12 */ "mm.......mm", + + // 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, + }, // WoodenHouse9x7Butcher + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouse9x7DoubleDoor: + // The data has been exported from the gallery Plains, area index 38, ID 87, created by Aloe_vera + { + // Size: + 11, 9, 9, // SizeX = 11, SizeY = 9, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 8, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 67: 3\n" /* stairs */ + "h: 17: 0\n" /* tree */ + "i: 5: 0\n" /* wood */ + "j: 64: 7\n" /* wooddoorblock */ + "k:102: 0\n" /* glasspane */ + "l: 64:12\n" /* wooddoorblock */ + "m: 19: 0\n" /* sponge */ + "n: 53: 2\n" /* woodstairs */ + "o: 53: 7\n" /* woodstairs */ + "p: 17: 4\n" /* tree */ + "q: 17: 8\n" /* tree */ + "r: 50: 3\n" /* torch */ + "s: 50: 4\n" /* torch */ + "t: 53: 6\n" /* woodstairs */ + "u: 53: 3\n" /* woodstairs */, + + // Block data: + // Level 0 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "aaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaa" + /* 7 */ "aaaaaaaaaaa" + /* 8 */ "aaaaaaaaaaa" + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "bbbbaaabbbb" + /* 1 */ "baaaaaaaaab" + /* 2 */ "baaaaaaaaab" + /* 3 */ "baaaaaaaaab" + /* 4 */ "baaaaaaaaab" + /* 5 */ "baaaaaaaaab" + /* 6 */ "baaaaaaaaab" + /* 7 */ "baaaaaaaaab" + /* 8 */ "bbbbaaabbbb" + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "....cde...." + /* 1 */ ".fffffffff." + /* 2 */ ".fffffffff." + /* 3 */ ".fffffffff." + /* 4 */ ".fffffffff." + /* 5 */ ".fffffffff." + /* 6 */ ".fffffffff." + /* 7 */ ".fffffffff." + /* 8 */ "....cge...." + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".hiihjhiih." + /* 2 */ ".i.......i." + /* 3 */ ".i.......i." + /* 4 */ ".h.......h." + /* 5 */ ".i.......i." + /* 6 */ ".i.......i." + /* 7 */ ".hiihjhiih." + /* 8 */ "..........." + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".hkkhlhkkh." + /* 2 */ ".k.......k." + /* 3 */ ".k.......k." + /* 4 */ ".h.......h." + /* 5 */ ".k.......k." + /* 6 */ ".k.......k." + /* 7 */ ".hkkhlhkkh." + /* 8 */ "..........." + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "nnnnnnnnnnn" + /* 1 */ "ohpppppppho" + /* 2 */ ".q..r.r..q." + /* 3 */ ".q.......q." + /* 4 */ ".q.......q." + /* 5 */ ".q.......q." + /* 6 */ ".q..s.s..q." + /* 7 */ "thpppppppht" + /* 8 */ "uuuuuuuuuuu" + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "nnnnnnnnnnn" + /* 2 */ "oiiiiiiiiio" + /* 3 */ ".i.......i." + /* 4 */ ".i.......i." + /* 5 */ ".i.......i." + /* 6 */ "tiiiiiiiiit" + /* 7 */ "uuuuuuuuuuu" + /* 8 */ "..........." + + // Level 7 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "nnnnnnnnnnn" + /* 3 */ "oiiiiiiiiio" + /* 4 */ ".i.......i." + /* 5 */ "tiiiiiiiiit" + /* 6 */ "uuuuuuuuuuu" + /* 7 */ "..........." + /* 8 */ "..........." + + // Level 8 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ "nnnnnnnnnnn" + /* 4 */ "iiiiiiiiiii" + /* 5 */ "uuuuuuuuuuu" + /* 6 */ "..........." + /* 7 */ "..........." + /* 8 */ "...........", + + // 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, + }, // WoodenHouse9x7DoubleDoor + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouseL13x14: + // The data has been exported from the gallery Plains, area index 39, ID 90, created by STR_Warrior + { + // Size: + 15, 10, 16, // SizeX = 15, SizeY = 10, SizeZ = 16 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 14, 9, 15, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "A: 50: 4\n" /* torch */ + "B: 50: 2\n" /* torch */ + "C: 53: 7\n" /* woodstairs */ + "D: 53: 4\n" /* woodstairs */ + "E: 53: 5\n" /* woodstairs */ + "F: 53: 6\n" /* woodstairs */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 43: 0\n" /* doubleslab */ + "h: 17: 0\n" /* tree */ + "i: 5: 0\n" /* wood */ + "j: 64: 7\n" /* wooddoorblock */ + "k: 96: 8\n" /* trapdoor */ + "l: 61: 2\n" /* furnace */ + "m: 19: 0\n" /* sponge */ + "n: 53: 3\n" /* woodstairs */ + "o: 85: 0\n" /* fence */ + "p: 53: 2\n" /* woodstairs */ + "q: 53: 1\n" /* woodstairs */ + "r: 53: 0\n" /* woodstairs */ + "s: 47: 0\n" /* bookshelf */ + "t:102: 0\n" /* glasspane */ + "u: 64:12\n" /* wooddoorblock */ + "v: 72: 0\n" /* woodplate */ + "w: 17: 4\n" /* tree */ + "x: 17: 8\n" /* tree */ + "y: 50: 3\n" /* torch */ + "z: 50: 1\n" /* torch */, + + // 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 */ "mmmmmmmmaaaaaaa" + /* 9 */ "mmmmmmmmaaaaaaa" + /* 10 */ "mmmmmmmmaaaaaaa" + /* 11 */ "mmmmmmmmaaaaaaa" + /* 12 */ "mmmmmmmmaaaaaaa" + /* 13 */ "mmmmmmmmaaaaaaa" + /* 14 */ "mmmmmmmmaaaaaaa" + /* 15 */ "mmmmmmmmaaaaaaa" + + // Level 1 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "bbbbbbaaabbbbbb" + /* 1 */ "baaaaaaaaaaaaab" + /* 2 */ "baaaaaaaaaaaaab" + /* 3 */ "baaaaaaaaaaaaab" + /* 4 */ "baaaaaaaaaaaaab" + /* 5 */ "baaaaaaaaaaaaab" + /* 6 */ "baaaaaaaaaaaaab" + /* 7 */ "baaaaaaaaaaaaab" + /* 8 */ "mmmmmmmmaaaaaab" + /* 9 */ "mmmmmmmmaaaaaab" + /* 10 */ "mmmmmmmmaaaaaab" + /* 11 */ "mmmmmmmmaaaaaab" + /* 12 */ "mmmmmmmmaaaaaab" + /* 13 */ "mmmmmmmmaaaaaab" + /* 14 */ "mmmmmmmmaaaaaab" + /* 15 */ "mmmmmmmmbbbbbbb" + + // Level 2 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "......cde......" + /* 1 */ ".fffffffffffff." + /* 2 */ ".fggggffffffff." + /* 3 */ ".fggggffffffff." + /* 4 */ ".fffffffffffff." + /* 5 */ ".fffffffffffff." + /* 6 */ ".fffffffffffff." + /* 7 */ "mfffffffffffff." + /* 8 */ "mmmmmmmmffffff." + /* 9 */ "mmmmmmmmffffff." + /* 10 */ "mmmmmmmmffffff." + /* 11 */ "mmmmmmmmffffff." + /* 12 */ "mmmmmmmmffffff." + /* 13 */ "mmmmmmmmffffff." + /* 14 */ "mmmmmmmmffffff." + /* 15 */ "mmmmmmmm......." + + // Level 3 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".hiiiihjhiiiih." + /* 2 */ ".i...k.......i." + /* 3 */ ".ilggg......ni." + /* 4 */ ".h..........oi." + /* 5 */ ".i..........pi." + /* 6 */ ".i.qor..qo...i." + /* 7 */ "mhiiiiiihp...h." + /* 8 */ "mmmmmmmmi....i." + /* 9 */ "mmmmmmmmin...i." + /* 10 */ "mmmmmmmmio..ni." + /* 11 */ "mmmmmmmmip..oi." + /* 12 */ "mmmmmmmmi...pi." + /* 13 */ "mmmmmmmmis..si." + /* 14 */ "mmmmmmmmhiiiih." + /* 15 */ "mmmmmmmm......." + + // Level 4 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".hittihuhittih." + /* 2 */ ".i...........i." + /* 3 */ ".i...........t." + /* 4 */ ".h..........vt." + /* 5 */ ".i...........t." + /* 6 */ ".i..v....v...i." + /* 7 */ "mhittttih....h." + /* 8 */ "mmmmmmmmi....i." + /* 9 */ "mmmmmmmmt....t." + /* 10 */ "mmmmmmmmtv...t." + /* 11 */ "mmmmmmmmt...vt." + /* 12 */ "mmmmmmmmt....t." + /* 13 */ "mmmmmmmmis..si." + /* 14 */ "mmmmmmmmhittih." + /* 15 */ "mmmmmmmm......." + + // Level 5 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".hwwwwwwwwwwwh." + /* 2 */ ".x....y.y....x." + /* 3 */ ".x...........x." + /* 4 */ ".xz..........x." + /* 5 */ ".x...........x." + /* 6 */ ".x......A....x." + /* 7 */ "mhwwwwwwhz..Bx." + /* 8 */ "mmmmmmmmx....x." + /* 9 */ "mmmmmmmmx....x." + /* 10 */ "mmmmmmmmx....x." + /* 11 */ "mmmmmmmmx....x." + /* 12 */ "mmmmmmmmx....x." + /* 13 */ "mmmmmmmmx.AA.x." + /* 14 */ "mmmmmmmmhwwwwh." + /* 15 */ "mmmmmmmm......." + + // Level 6 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "ppppppppppppppq" + /* 1 */ "riiiiiiiiiiiiiq" + /* 2 */ "riCCCCCCCCCCDiq" + /* 3 */ "riE.........Diq" + /* 4 */ "riE.........Diq" + /* 5 */ "riE.........Diq" + /* 6 */ "riEFFFFFFF..Diq" + /* 7 */ "riiiiiiiiE..Diq" + /* 8 */ "rnnnnnnriE..Diq" + /* 9 */ "mmmmmmmriE..Diq" + /* 10 */ "mmmmmmmriE..Diq" + /* 11 */ "mmmmmmmriE..Diq" + /* 12 */ "mmmmmmmriE..Diq" + /* 13 */ "mmmmmmmriEFFDiq" + /* 14 */ "mmmmmmmriiiiiiq" + /* 15 */ "mmmmmmmrnnnnnnn" + + // Level 7 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "mmmmmmmmmmmmmmm" + /* 1 */ "mrpppppppppppqm" + /* 2 */ "mriiiiiiiiiiiqm" + /* 3 */ "mriiiiiiiiiiiqm" + /* 4 */ "mriiiiiiiiiiiqm" + /* 5 */ "mriiiiiiiiiiiqm" + /* 6 */ "mriiiiiiiiiiiqm" + /* 7 */ "mrnnnnnnniiiiqm" + /* 8 */ "mmmmmmmmriiiiqm" + /* 9 */ "mmmmmmmmriiiiqm" + /* 10 */ "mmmmmmmmriiiiqm" + /* 11 */ "mmmmmmmmriiiiqm" + /* 12 */ "mmmmmmmmriiiiqm" + /* 13 */ "mmmmmmmmriiiiqm" + /* 14 */ "mmmmmmmmnnnnnqm" + /* 15 */ "mmmmmmmmmmmmmmm" + + // Level 8 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "mmmmmmmmmmmmmmm" + /* 1 */ "mmmmmmmmmmmmmmm" + /* 2 */ "mmpppppppppppmm" + /* 3 */ "mmriiiiiiiiiqmm" + /* 4 */ "mmriiiiiiiiiqmm" + /* 5 */ "mmriiiiiiiiiqmm" + /* 6 */ "mmnnnnnnnniiqmm" + /* 7 */ "mmmmmmmmmriiqmm" + /* 8 */ "mmmmmmmmmriiqmm" + /* 9 */ "mmmmmmmmmriiqmm" + /* 10 */ "mmmmmmmmmriiqmm" + /* 11 */ "mmmmmmmmmriiqmm" + /* 12 */ "mmmmmmmmmriiqmm" + /* 13 */ "mmmmmmmmmnnnqmm" + /* 14 */ "mmmmmmmmmmmmmmm" + /* 15 */ "mmmmmmmmmmmmmmm" + + // Level 9 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "mmmmmmmmmmmmmmm" + /* 1 */ "mmmmmmmmmmmmmmm" + /* 2 */ "mmmmmmmmmmmmmmm" + /* 3 */ "mmmrpppppppqmmm" + /* 4 */ "mmmriiiiiiiqmmm" + /* 5 */ "mmmrnnnnnnrqmmm" + /* 6 */ "mmmmmmmmmmrqmmm" + /* 7 */ "mmmmmmmmmmrqmmm" + /* 8 */ "mmmmmmmmmmrqmmm" + /* 9 */ "mmmmmmmmmmrqmmm" + /* 10 */ "mmmmmmmmmmrqmmm" + /* 11 */ "mmmmmmmmmmrqmmm" + /* 12 */ "mmmmmmmmmmrnmmm" + /* 13 */ "mmmmmmmmmmmmmmm" + /* 14 */ "mmmmmmmmmmmmmmm" + /* 15 */ "mmmmmmmmmmmmmmm", + + // Connectors: + "-1: 7, 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, + }, // WoodenHouseL13x14 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenHouseL14x14: // The data has been exported from the gallery Plains, area index 0, ID 4, created by Aloe_vera { // Size: @@ -1441,7 +3064,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 15 */ "mmmmmmmmmmren...", // Connectors: - "-1: 9, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 9, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1460,609 +3083,25 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, - }, // PlainsVillage_4 + }, // WoodenHouseL14x14 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_60: - // The data has been exported from the gallery Plains, area index 17, ID 60, created by Aloe_vera + // WoodenHouseL9x9: + // The data has been exported from the gallery Plains, area index 42, ID 93, created by xoft { // Size: - 10, 2, 7, // SizeX = 10, SizeY = 2, SizeZ = 7 + 11, 8, 11, // SizeX = 11, SizeY = 8, SizeZ = 11 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 9, 1, 6, // MaxX, MaxY, MaxZ + 10, 7, 10, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 17: 0\n" /* tree */ - "b: 60: 7\n" /* tilleddirt */ - "c: 8: 0\n" /* water */ - "d: 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 */ ".........." - /* 1 */ ".dddddddd." - /* 2 */ ".dddddddd." - /* 3 */ ".........." - /* 4 */ ".dddddddd." - /* 5 */ ".dddddddd." - /* 6 */ "..........", - - // Connectors: - "-1: 9, 0, 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, - }, // PlainsVillage_60 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_66: - // 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): - 0, 0, 0, // MinX, MinY, MinZ - 11, 6, 6, // MaxX, MaxY, MaxZ - - // Block definitions: - ".: 0: 0\n" /* air */ - "a: 2: 0\n" /* grass */ - "b: 3: 0\n" /* dirt */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 64: 7\n" /* wooddoorblock */ - "h: 53: 3\n" /* woodstairs */ - "i: 53: 1\n" /* woodstairs */ - "j: 85: 0\n" /* fence */ - "k: 53: 0\n" /* woodstairs */ - "l: 53: 2\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: 50: 4\n" /* torch */ - "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 */ - "x: 5: 0\n" /* wood */, - - // Block data: - // Level 0 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "aaaaaaabbbaa" - /* 1 */ "abbbbbbbbbba" - /* 2 */ "abbbbbbbbbba" - /* 3 */ "abbbbbbbbbba" - /* 4 */ "abbbbbbbbbba" - /* 5 */ "abbbbbbbbbba" - /* 6 */ "aaaaaaaaaaaa" - - // Level 1 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ ".......cde.." - /* 1 */ ".ffffffffff." - /* 2 */ ".ffffffffff." - /* 3 */ ".ffffffffff." - /* 4 */ ".ffffffffff." - /* 5 */ ".ffffffffff." - /* 6 */ "............" - - // Level 2 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ ".fffffffgff." - /* 2 */ ".fh.ijk...f." - /* 3 */ ".fj.......f." - /* 4 */ ".fl.ijkijkf." - /* 5 */ ".ffffffffff." - /* 6 */ "............" - - // Level 3 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ ".fnnfnnfoff." - /* 2 */ ".n..pq.p.pn." - /* 3 */ ".nq.......n." - /* 4 */ ".n..rq.rq.n." - /* 5 */ ".fnnfnnfnnf." - /* 6 */ "............" - - // Level 4 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "llllllllllll" - /* 1 */ "sffffffffffs" - /* 2 */ ".fttttttttf." - /* 3 */ ".fu......vf." - /* 4 */ ".fttttttttf." - /* 5 */ "wffffffffffw" - /* 6 */ "hhhhhhhhhhhh" - - // Level 5 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "llllllllllll" - /* 2 */ "sxxxxxxxxxxs" - /* 3 */ ".xxxxxxxxxx." - /* 4 */ "wxxxxxxxxxxw" - /* 5 */ "hhhhhhhhhhhh" - /* 6 */ "............" - - // Level 6 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "............" - /* 2 */ "llllllllllll" - /* 3 */ "xxxxxxxxxxxx" - /* 4 */ "hhhhhhhhhhhh" - /* 5 */ "............" - /* 6 */ "............", - - // Connectors: - "-1: 8, 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, - }, // PlainsVillage_66 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_87: - // The data has been exported from the gallery Plains, area index 38, ID 87, created by Aloe_vera - { - // 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: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ "....abc...." - /* 1 */ ".ddddddddd." - /* 2 */ ".ddddddddd." - /* 3 */ ".ddddddddd." - /* 4 */ ".ddddddddd." - /* 5 */ ".ddddddddd." - /* 6 */ ".ddddddddd." - /* 7 */ ".ddddddddd." - /* 8 */ "....aec...." - - // Level 1 - /* 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 2 - /* 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 3 - /* 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 4 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "kkkkkkkkkkk" - /* 2 */ "lgggggggggl" - /* 3 */ ".g.......g." - /* 4 */ ".g.......g." - /* 5 */ ".g.......g." - /* 6 */ "rgggggggggr" - /* 7 */ "sssssssssss" - /* 8 */ "..........." - - // Level 5 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "kkkkkkkkkkk" - /* 3 */ "lgggggggggl" - /* 4 */ ".g.......g." - /* 5 */ "rgggggggggr" - /* 6 */ "sssssssssss" - /* 7 */ "..........." - /* 8 */ "..........." - - // Level 6 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "..........." - /* 3 */ "kkkkkkkkkkk" - /* 4 */ "ggggggggggg" - /* 5 */ "sssssssssss" - /* 6 */ "..........." - /* 7 */ "..........." - /* 8 */ "...........", - - // Connectors: - "-1: 5, 0, 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, - }, // PlainsVillage_87 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_90: - // The data has been exported from the gallery Plains, area index 39, ID 90, created by STR_Warrior - { - // Size: - 15, 8, 16, // SizeX = 15, SizeY = 8, SizeZ = 16 - - // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 14, 7, 15, // 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: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ "......abc......" - /* 1 */ ".ddddddddddddd." - /* 2 */ ".deeeedddddddd." - /* 3 */ ".deeeedddddddd." - /* 4 */ ".ddddddddddddd." - /* 5 */ ".ddddddddddddd." - /* 6 */ ".ddddddddddddd." - /* 7 */ "mddddddddddddd." - /* 8 */ "mmmmmmmmdddddd." - /* 9 */ "mmmmmmmmdddddd." - /* 10 */ "mmmmmmmmdddddd." - /* 11 */ "mmmmmmmmdddddd." - /* 12 */ "mmmmmmmmdddddd." - /* 13 */ "mmmmmmmmdddddd." - /* 14 */ "mmmmmmmmdddddd." - /* 15 */ "mmmmmmmm......." - - // Level 1 - /* 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 */ "mfggggggfn...f." - /* 8 */ "mmmmmmmmg....g." - /* 9 */ "mmmmmmmmgk...g." - /* 10 */ "mmmmmmmmgl..kg." - /* 11 */ "mmmmmmmmgn..lg." - /* 12 */ "mmmmmmmmg...ng." - /* 13 */ "mmmmmmmmgq..qg." - /* 14 */ "mmmmmmmmfggggf." - /* 15 */ "mmmmmmmm......." - - // Level 2 - /* 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 */ "mfgrrrrgf....f." - /* 8 */ "mmmmmmmmg....g." - /* 9 */ "mmmmmmmmr....r." - /* 10 */ "mmmmmmmmrt...r." - /* 11 */ "mmmmmmmmr...tr." - /* 12 */ "mmmmmmmmr....r." - /* 13 */ "mmmmmmmmgq..qg." - /* 14 */ "mmmmmmmmfgrrgf." - /* 15 */ "mmmmmmmm......." - - // Level 3 - /* 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 */ "mfuuuuuufx..zv." - /* 8 */ "mmmmmmmmv....v." - /* 9 */ "mmmmmmmmv....v." - /* 10 */ "mmmmmmmmv....v." - /* 11 */ "mmmmmmmmv....v." - /* 12 */ "mmmmmmmmv....v." - /* 13 */ "mmmmmmmmv.yy.v." - /* 14 */ "mmmmmmmmfuuuuf." - /* 15 */ "mmmmmmmm......." - - // Level 4 - /* 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 5 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "mmmmmmmmmmmmmmm" - /* 1 */ "mpnnnnnnnnnnnom" - /* 2 */ "mpgggggggggggom" - /* 3 */ "mpgggggggggggom" - /* 4 */ "mpgggggggggggom" - /* 5 */ "mpgggggggggggom" - /* 6 */ "mpgggggggggggom" - /* 7 */ "mpkkkkkkkggggom" - /* 8 */ "mmmmmmmmpggggom" - /* 9 */ "mmmmmmmmpggggom" - /* 10 */ "mmmmmmmmpggggom" - /* 11 */ "mmmmmmmmpggggom" - /* 12 */ "mmmmmmmmpggggom" - /* 13 */ "mmmmmmmmpggggom" - /* 14 */ "mmmmmmmmkkkkkom" - /* 15 */ "mmmmmmmmmmmmmmm" - - // Level 6 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "mmmmmmmmmmmmmmm" - /* 1 */ "mmmmmmmmmmmmmmm" - /* 2 */ "mmnnnnnnnnnnnmm" - /* 3 */ "mmpgggggggggomm" - /* 4 */ "mmpgggggggggomm" - /* 5 */ "mmpgggggggggomm" - /* 6 */ "mmkkkkkkkkggomm" - /* 7 */ "mmmmmmmmmpggomm" - /* 8 */ "mmmmmmmmmpggomm" - /* 9 */ "mmmmmmmmmpggomm" - /* 10 */ "mmmmmmmmmpggomm" - /* 11 */ "mmmmmmmmmpggomm" - /* 12 */ "mmmmmmmmmpggomm" - /* 13 */ "mmmmmmmmmkkkomm" - /* 14 */ "mmmmmmmmmmmmmmm" - /* 15 */ "mmmmmmmmmmmmmmm" - - // Level 7 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "mmmmmmmmmmmmmmm" - /* 1 */ "mmmmmmmmmmmmmmm" - /* 2 */ "mmmmmmmmmmmmmmm" - /* 3 */ "mmmpnnnnnnnommm" - /* 4 */ "mmmpgggggggommm" - /* 5 */ "mmmpkkkkkkpommm" - /* 6 */ "mmmmmmmmmmpommm" - /* 7 */ "mmmmmmmmmmpommm" - /* 8 */ "mmmmmmmmmmpommm" - /* 9 */ "mmmmmmmmmmpommm" - /* 10 */ "mmmmmmmmmmpommm" - /* 11 */ "mmmmmmmmmmpommm" - /* 12 */ "mmmmmmmmmmpkmmm" - /* 13 */ "mmmmmmmmmmmmmmm" - /* 14 */ "mmmmmmmmmmmmmmm" - /* 15 */ "mmmmmmmmmmmmmmm", - - // Connectors: - "-1: 7, 0, 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, - }, // PlainsVillage_90 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_91: - // 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): - 0, 0, 0, // MinX, MinY, MinZ - 8, 6, 6, // MaxX, MaxY, MaxZ - - // Block definitions: - ".: 0: 0\n" /* air */ - "a: 2: 0\n" /* grass */ - "b: 3: 0\n" /* dirt */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ "c: 67: 0\n" /* stairs */ "d: 67: 2\n" /* stairs */ "e: 67: 1\n" /* stairs */ @@ -2075,203 +3114,140 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "l: 53: 2\n" /* woodstairs */ "m: 19: 0\n" /* sponge */ "n: 53: 7\n" /* woodstairs */ - "o: 50: 3\n" /* torch */ - "p: 53: 6\n" /* woodstairs */ - "q: 53: 3\n" /* woodstairs */, + "o: 53: 1\n" /* woodstairs */ + "p: 50: 3\n" /* torch */ + "q: 50: 4\n" /* torch */ + "r: 53: 6\n" /* woodstairs */ + "s: 50: 1\n" /* torch */ + "t: 50: 2\n" /* torch */ + "u: 53: 3\n" /* woodstairs */ + "v: 53: 0\n" /* woodstairs */ + "w: 53: 5\n" /* woodstairs */ + "x: 53: 4\n" /* woodstairs */, // Block data: // Level 0 - /* z\x* 012345678 */ - /* 0 */ "aaabbbaaa" - /* 1 */ "abbbbbbba" - /* 2 */ "abbbbbbba" - /* 3 */ "abbbbbbba" - /* 4 */ "abbbbbbba" - /* 5 */ "abbbbbbba" - /* 6 */ "aaaaaaaaa" + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "aaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaa" + /* 7 */ "aaaaaaaaaaa" + /* 8 */ "aaaaaaaaaaa" + /* 9 */ "aaaaaaaaaaa" + /* 10 */ "aaaaaaaaaaa" // Level 1 - /* z\x* 012345678 */ - /* 0 */ "...cde..." - /* 1 */ ".fffffff." - /* 2 */ ".fffffff." - /* 3 */ ".fffffff." - /* 4 */ ".fffffff." - /* 5 */ ".fffffff." - /* 6 */ "........." + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "bbbbaaabbbb" + /* 1 */ "baaaaaaaaab" + /* 2 */ "baaaaaaaaab" + /* 3 */ "baaaaaaaaab" + /* 4 */ "baaaaaaaaab" + /* 5 */ "baaaaaaaaab" + /* 6 */ "bbbbbaaaaab" + /* 7 */ "bbbbbaaaaab" + /* 8 */ "bbbbbaaaaab" + /* 9 */ "bbbbbaaaaab" + /* 10 */ "bbbbbbbbbbb" // Level 2 - /* z\x* 012345678 */ - /* 0 */ "........." - /* 1 */ ".ghhihhg." - /* 2 */ ".h.....h." - /* 3 */ ".h.....h." - /* 4 */ ".h.....h." - /* 5 */ ".ghhhhhg." - /* 6 */ "........." + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "....cde...." + /* 1 */ ".fffffffff." + /* 2 */ ".fffffffff." + /* 3 */ ".fffffffff." + /* 4 */ ".fffffffff." + /* 5 */ ".fffffffff." + /* 6 */ ".....fffff." + /* 7 */ "mmmm.fffff." + /* 8 */ "mmmm.fffff." + /* 9 */ "mmmm.fffff." + /* 10 */ "mmmm......." // Level 3 - /* z\x* 012345678 */ - /* 0 */ "........." - /* 1 */ ".gjhkhjg." - /* 2 */ ".j.....j." - /* 3 */ ".j.....j." - /* 4 */ ".j.....j." - /* 5 */ ".gjjhjjg." - /* 6 */ "........." - - // Level 4 - /* z\x* 012345678 */ - /* 0 */ "lllllllll" - /* 1 */ "nghhhhhgn" - /* 2 */ ".h.o.o.h." - /* 3 */ ".h.....h." - /* 4 */ ".h.....h." - /* 5 */ "pghhhhhgp" - /* 6 */ "qqqqqqqqq" - - // Level 5 - /* z\x* 012345678 */ - /* 0 */ "........." - /* 1 */ "lllllllll" - /* 2 */ "nhhhhhhhn" - /* 3 */ ".h.....h." - /* 4 */ "phhhhhhhp" - /* 5 */ "qqqqqqqqq" - /* 6 */ "........." - - // Level 6 - /* z\x* 012345678 */ - /* 0 */ "........." - /* 1 */ "........." - /* 2 */ "lllllllll" - /* 3 */ "hhhhhhhhh" - /* 4 */ "qqqqqqqqq" - /* 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, - }, // PlainsVillage_91 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_92: - // The data has been exported from the gallery Plains, area index 41, ID 92, created by xoft - { - // 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: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ "....abc...." - /* 1 */ ".ddddddddd." - /* 2 */ ".ddddddddd." - /* 3 */ ".ddddddddd." - /* 4 */ ".ddddddddd." - /* 5 */ ".ddddddddd." - /* 6 */ "..........." - - // Level 1 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ ".efffgfffe." - /* 2 */ ".f.......f." - /* 3 */ ".f.......f." - /* 4 */ ".f.......f." - /* 5 */ ".efffffffe." - /* 6 */ "..........." - - // Level 2 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".ehhfifhhe." + /* 1 */ ".ghhhihhhg." /* 2 */ ".h.......h." /* 3 */ ".h.......h." /* 4 */ ".h.......h." - /* 5 */ ".ehhhfhhhe." - /* 6 */ "..........." - - // Level 3 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "jjjjjjjjjjj" - /* 1 */ "kfffffffffk" - /* 2 */ ".f..l.l.ff." - /* 3 */ ".f......ff." - /* 4 */ ".f......ff." - /* 5 */ "nfffffffffn" - /* 6 */ "ooooooooooo" + /* 5 */ ".ghhhg...h." + /* 6 */ ".....h...h." + /* 7 */ "mmmm.h...h." + /* 8 */ "mmmm.h...h." + /* 9 */ "mmmm.ghhhg." + /* 10 */ "mmmm......." // Level 4 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ "jjjjjjjjjjj" - /* 2 */ "kfffffffffk" - /* 3 */ ".fffffffff." - /* 4 */ "nfffffffffn" - /* 5 */ "ooooooooooo" - /* 6 */ "..........." + /* 1 */ ".gjjhkhjjg." + /* 2 */ ".j.......j." + /* 3 */ ".j.......j." + /* 4 */ ".j.......j." + /* 5 */ ".gjjjg...h." + /* 6 */ ".....j...j." + /* 7 */ "mmmm.j...j." + /* 8 */ "mmmm.j...j." + /* 9 */ "mmmm.gjjjg." + /* 10 */ "mmmm......." // Level 5 /* z\x* 1 */ /* * 01234567890 */ + /* 0 */ "lllllllllll" + /* 1 */ "nhhhhhhhhho" + /* 2 */ ".h..p.p..ho" + /* 3 */ ".h.......ho" + /* 4 */ ".h...q...ho" + /* 5 */ "rhhhhhs.tho" + /* 6 */ "uuuuuh...ho" + /* 7 */ "mmmmvh...ho" + /* 8 */ "mmmmvh...ho" + /* 9 */ "mmmmvhhhhho" + /* 10 */ "mmmmvw...xo" + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "lllllllllo." + /* 2 */ "nhhhhhhhho." + /* 3 */ ".h......ho." + /* 4 */ "rhhhhhh.ho." + /* 5 */ "uuuuuuh.ho." + /* 6 */ ".....vh.ho." + /* 7 */ "mmmm.vh.ho." + /* 8 */ "mmmm.vh.ho." + /* 9 */ "mmmm.vhhho." + /* 10 */ "mmmm.vw.xo." + + // Level 7 + /* z\x* 1 */ + /* * 01234567890 */ /* 0 */ "..........." /* 1 */ "..........." - /* 2 */ "jjjjjjjjjjj" - /* 3 */ "fffffffffff" - /* 4 */ "ooooooooooo" - /* 5 */ "..........." - /* 6 */ "...........", + /* 2 */ "lllllllll.." + /* 3 */ "hhhhhhhho.." + /* 4 */ "uuuuuuvho.." + /* 5 */ "......vho.." + /* 6 */ "......vho.." + /* 7 */ "mmmm..vho.." + /* 8 */ "mmmm..vho.." + /* 9 */ "mmmm..vho.." + /* 10 */ "mmmm..vho..", // Connectors: - "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */, + "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2290,288 +3266,169 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, - }, // PlainsVillage_92 + }, // WoodenHouseL9x9 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_93: - // The data has been exported from the gallery Plains, area index 42, ID 93, created by xoft + // WoodenHouseU13x9: + // The data has been exported from the gallery Plains, area index 43, ID 94, created by xoft { // Size: - 11, 6, 11, // SizeX = 11, SizeY = 6, SizeZ = 11 + 15, 8, 11, // SizeX = 15, SizeY = 8, SizeZ = 11 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 10, 5, 10, // MaxX, MaxY, MaxZ + 14, 7, 10, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h: 5: 0\n" /* wood */ + "i: 64: 7\n" /* wooddoorblock */ + "j:102: 0\n" /* glasspane */ + "k: 64:12\n" /* wooddoorblock */ + "l: 53: 2\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 */ + "n: 53: 0\n" /* woodstairs */ + "o: 53: 1\n" /* woodstairs */ + "p: 50: 3\n" /* torch */ + "q: 50: 4\n" /* torch */ "r: 50: 2\n" /* torch */ - "s: 53: 3\n" /* woodstairs */ - "t: 53: 0\n" /* woodstairs */ + "s: 50: 1\n" /* torch */ + "t: 53: 3\n" /* woodstairs */ "u: 53: 5\n" /* woodstairs */ "v: 53: 4\n" /* woodstairs */, // Block data: // Level 0 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "....abc...." - /* 1 */ ".ddddddddd." - /* 2 */ ".ddddddddd." - /* 3 */ ".ddddddddd." - /* 4 */ ".ddddddddd." - /* 5 */ ".ddddddddd." - /* 6 */ ".....ddddd." - /* 7 */ "mmmm.ddddd." - /* 8 */ "mmmm.ddddd." - /* 9 */ "mmmm.ddddd." - /* 10 */ "mmmm......." + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "aaaaaaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaaaaaa" + /* 2 */ "aaaaaaaaaaaaaaa" + /* 3 */ "aaaaaaaaaaaaaaa" + /* 4 */ "aaaaaaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaaaaaa" + /* 7 */ "aaaaaaaaaaaaaaa" + /* 8 */ "aaaaaaaaaaaaaaa" + /* 9 */ "aaaaaaaaaaaaaaa" + /* 10 */ "aaaaaaaaaaaaaaa" // Level 1 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".efffgfffe." - /* 2 */ ".f.......f." - /* 3 */ ".f.......f." - /* 4 */ ".f.......f." - /* 5 */ ".efffe...f." - /* 6 */ ".....f...f." - /* 7 */ "mmmm.f...f." - /* 8 */ "mmmm.f...f." - /* 9 */ "mmmm.efffe." - /* 10 */ "mmmm......." + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "bbbbbbaaabbbbbb" + /* 1 */ "baaaaaaaaaaaaab" + /* 2 */ "baaaaaaaaaaaaab" + /* 3 */ "baaaaaaaaaaaaab" + /* 4 */ "baaaaaaaaaaaaab" + /* 5 */ "baaaaaaaaaaaaab" + /* 6 */ "baaaaabbbaaaaab" + /* 7 */ "baaaaabbbaaaaab" + /* 8 */ "baaaaabbbaaaaab" + /* 9 */ "baaaaabbbaaaaab" + /* 10 */ "bbbbbbbbbbbbbbb" // Level 2 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".ehhfifhhe." - /* 2 */ ".h.......h." - /* 3 */ ".h.......h." - /* 4 */ ".h.......h." - /* 5 */ ".ehhhe...f." - /* 6 */ ".....h...h." - /* 7 */ "mmmm.h...h." - /* 8 */ "mmmm.h...h." - /* 9 */ "mmmm.ehhhe." - /* 10 */ "mmmm......." + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "......cde......" + /* 1 */ ".fffffffffffff." + /* 2 */ ".fffffffffffff." + /* 3 */ ".fffffffffffff." + /* 4 */ ".fffffffffffff." + /* 5 */ ".fffffffffffff." + /* 6 */ ".fffff...fffff." + /* 7 */ ".fffff...fffff." + /* 8 */ ".fffff...fffff." + /* 9 */ ".fffff...fffff." + /* 10 */ "..............." // Level 3 - /* 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 */ "mmmmtf...fl" - /* 8 */ "mmmmtf...fl" - /* 9 */ "mmmmtfffffl" - /* 10 */ "mmmmtu...vl" - - // Level 4 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "jjjjjjjjjl." - /* 2 */ "kffffffffl." - /* 3 */ ".f......fl." - /* 4 */ "pffffff.fl." - /* 5 */ "ssssssf.fl." - /* 6 */ ".....tf.fl." - /* 7 */ "mmmm.tf.fl." - /* 8 */ "mmmm.tf.fl." - /* 9 */ "mmmm.tfffl." - /* 10 */ "mmmm.tu.vl." - - // Level 5 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "jjjjjjjjj.." - /* 3 */ "ffffffffl.." - /* 4 */ "sssssstfl.." - /* 5 */ "......tfl.." - /* 6 */ "......tfl.." - /* 7 */ "mmmm..tfl.." - /* 8 */ "mmmm..tfl.." - /* 9 */ "mmmm..tfl.." - /* 10 */ "mmmm..tfl..", - - // Connectors: - "-1: 5, 0, 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, - }, // PlainsVillage_93 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_94: - // The data has been exported from the gallery Plains, area index 43, ID 94, created by xoft - { - // Size: - 15, 6, 11, // SizeX = 15, SizeY = 6, SizeZ = 11 - - // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 14, 5, 10, // MaxX, MaxY, MaxZ - - // Block definitions: - ".: 0: 0\n" /* air */ - "a: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ "......abc......" - /* 1 */ ".ddddddddddddd." - /* 2 */ ".ddddddddddddd." - /* 3 */ ".ddddddddddddd." - /* 4 */ ".ddddddddddddd." - /* 5 */ ".ddddddddddddd." - /* 6 */ ".ddddd...ddddd." - /* 7 */ ".ddddd...ddddd." - /* 8 */ ".ddddd...ddddd." - /* 9 */ ".ddddd...ddddd." - /* 10 */ "..............." - - // Level 1 /* 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 2 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "..............." - /* 1 */ ".ehhhhfifhhhhe." + /* 1 */ ".ghhhhhihhhhhg." /* 2 */ ".h...........h." /* 3 */ ".h...........h." /* 4 */ ".h...........h." - /* 5 */ ".f...ehhhe...f." + /* 5 */ ".h...ghhhg...h." /* 6 */ ".h...h...h...h." /* 7 */ ".h...h...h...h." /* 8 */ ".h...h...h...h." - /* 9 */ ".ehhhe...ehhhe." + /* 9 */ ".ghhhg...ghhhg." /* 10 */ "..............." - // Level 3 - /* 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 4 /* 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." + /* 1 */ ".gjjjjhkhjjjjg." + /* 2 */ ".j...........j." + /* 3 */ ".j...........j." + /* 4 */ ".j...........j." + /* 5 */ ".h...gjjjg...h." + /* 6 */ ".j...j...j...j." + /* 7 */ ".j...j...j...j." + /* 8 */ ".j...j...j...j." + /* 9 */ ".gjjjg...gjjjg." + /* 10 */ "..............." // Level 5 /* z\x* 11111 */ /* * 012345678901234 */ + /* 0 */ "lllllllllllllll" + /* 1 */ "nhhhhhhhhhhhhho" + /* 2 */ "nh....p.p....ho" + /* 3 */ "nh...........ho" + /* 4 */ "nh...q...q...ho" + /* 5 */ "nh..rhhhhhs..ho" + /* 6 */ "nh...httth...ho" + /* 7 */ "nh...ho.nh...ho" + /* 8 */ "nh...ho.nh...ho" + /* 9 */ "nhhhhho.nhhhhho" + /* 10 */ "nu...vo.nu...vo" + + // Level 6 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".llllllllllllo." + /* 2 */ ".nhhhhhhhhhhho." + /* 3 */ ".nhhhhhhhhhhho." + /* 4 */ ".nhhhhhhhhhhho." + /* 5 */ ".nhhhotttthhho." + /* 6 */ ".nhhho...nhhho." + /* 7 */ ".nhhho...nhhho." + /* 8 */ ".nhhho...nhhho." + /* 9 */ ".nhhho...nhhho." + /* 10 */ ".nu.vo...nu.vo." + + // Level 7 + /* 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..", + /* 2 */ "..nllllllllll.." + /* 3 */ "..nhhhhhhhhho.." + /* 4 */ "..nhotttttnho.." + /* 5 */ "..nho.....nho.." + /* 6 */ "..nho.....nho.." + /* 7 */ "..nho.....nho.." + /* 8 */ "..nho.....nho.." + /* 9 */ "..nho.....nho.." + /* 10 */ "..nho.....nho..", // Connectors: - "-1: 7, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 7, 2, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2590,446 +3447,338 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, - }, // PlainsVillage_94 + }, // WoodenHouseU13x9 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_97: - // The data has been exported from the gallery Plains, area index 46, ID 97, created by Aloe_vera + // WoodenMill5x5: + // The data has been exported from the gallery Plains, area index 60, ID 111, created by Aloe_vera { // Size: - 11, 6, 7, // SizeX = 11, SizeY = 6, SizeZ = 7 + 9, 18, 13, // SizeX = 9, SizeY = 18, SizeZ = 13 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 10, 5, 6, // MaxX, MaxY, MaxZ + 8, 17, 12, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ "....abc...." - /* 1 */ ".ddddddddd." - /* 2 */ ".ddddddddd." - /* 3 */ ".ddddddddd." - /* 4 */ ".ddddddddd." - /* 5 */ ".ddddddddd." - /* 6 */ "..........." - - // Level 1 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".efffgfffe." - /* 2 */ ".fh.....hf." - /* 3 */ ".fi.....if." - /* 4 */ ".fj.kil.jf." - /* 5 */ ".efffffffe." - /* 6 */ "..........." - - // Level 2 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".ennfofnne." - /* 2 */ ".n..p.p..n." - /* 3 */ ".nq.....qn." - /* 4 */ ".n...q...n." - /* 5 */ ".ennnfnnne." - /* 6 */ "..........." - - // Level 3 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "jjjjjjjjjjj" - /* 1 */ "rfffffffffr" - /* 2 */ ".fsssssssf." - /* 3 */ ".ft.....uf." - /* 4 */ ".fsssssssf." - /* 5 */ "vfffffffffv" - /* 6 */ "hhhhhhhhhhh" - - // Level 4 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "jjjjjjjjjjj" - /* 2 */ "rfffffffffr" - /* 3 */ ".f.......f." - /* 4 */ "vfffffffffv" - /* 5 */ "hhhhhhhhhhh" - /* 6 */ "..........." - - // Level 5 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "jjjjjjjjjjj" - /* 3 */ "fffffffffff" - /* 4 */ "hhhhhhhhhhh" - /* 5 */ "..........." - /* 6 */ "...........", - - // Connectors: - "-1: 5, 0, 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, - }, // PlainsVillage_97 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_98: - // The data has been exported from the gallery Plains, area index 47, ID 98, created by Aloe_vera - { - // Size: - 12, 7, 9, // SizeX = 12, SizeY = 7, SizeZ = 9 - - // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 11, 6, 8, // MaxX, MaxY, MaxZ - - // Block definitions: - ".: 0: 0\n" /* air */ - "a: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "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 */ "....abbc...." - /* 1 */ ".dddddddddd." - /* 2 */ ".dddddddddd." - /* 3 */ ".dddddddddd." - /* 4 */ ".dddddddddd." - /* 5 */ ".dddddddddd." - /* 6 */ ".dddddddddd." - /* 7 */ ".dddddddddd." - /* 8 */ "............" - - // Level 1 - /* 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 2 - /* 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 3 - /* 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 4 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "kkkkkkkkkkkk" - /* 2 */ "sffffffffffs" - /* 3 */ ".fttttttttf." - /* 4 */ ".f........f." - /* 5 */ ".fttttttttf." - /* 6 */ "wffffffffffw" - /* 7 */ "iiiiiiiiiiii" - /* 8 */ "............" - - // Level 5 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "............" - /* 2 */ "kkkkkkkkkkkk" - /* 3 */ "sffffffffffs" - /* 4 */ ".f........f." - /* 5 */ "wffffffffffw" - /* 6 */ "iiiiiiiiiiii" - /* 7 */ "............" - /* 8 */ "............" - - // Level 6 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "............" - /* 2 */ "............" - /* 3 */ "kkkkkkkkkkkk" - /* 4 */ "ffffffffffff" - /* 5 */ "iiiiiiiiiiii" - /* 6 */ "............" - /* 7 */ "............" - /* 8 */ "............", - - // Connectors: - "-1: 5, 0, 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, - }, // PlainsVillage_98 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // PlainsVillage_99: - // The data has been exported from the gallery Plains, area index 48, ID 99, created by Aloe_vera - { - // Size: - 11, 7, 13, // SizeX = 11, SizeY = 7, SizeZ = 13 - - // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 6, 12, // MaxX, MaxY, MaxZ - - // Block definitions: - ".: 0: 0\n" /* air */ - "a: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "e: 43: 0\n" /* doubleslab */ - "f: 2: 0\n" /* grass */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 4: 0\n" /* cobblestone */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 67: 3\n" /* stairs */ "g: 17: 0\n" /* tree */ "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j: 53: 3\n" /* woodstairs */ - "k: 85: 0\n" /* fence */ - "l: 53: 2\n" /* woodstairs */ + "i: 54: 4\n" /* chest */ + "j:154: 4\n" /* hopper */ + "k: 64: 4\n" /* wooddoorblock */ + "l:102: 0\n" /* glasspane */ "m: 19: 0\n" /* sponge */ - "n:102: 0\n" /* glasspane */ + "n: 85: 0\n" /* fence */ "o: 64:12\n" /* wooddoorblock */ - "p: 72: 0\n" /* woodplate */ - "q: 53: 7\n" /* woodstairs */ - "r: 50: 1\n" /* torch */ - "s: 50: 2\n" /* torch */ - "t: 53: 6\n" /* woodstairs */, + "p: 50: 2\n" /* torch */ + "q: 35: 0\n" /* wool */ + "r: 17: 4\n" /* tree */ + "s: 17: 8\n" /* tree */ + "t: 53: 2\n" /* woodstairs */ + "u: 53: 7\n" /* woodstairs */ + "v: 53: 6\n" /* woodstairs */ + "w: 53: 3\n" /* woodstairs */, // Block data: // Level 0 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "....abc...." - /* 1 */ ".ddddddddd." - /* 2 */ ".deeeedddd." - /* 3 */ ".deeeedddd." - /* 4 */ ".deeeedddd." - /* 5 */ ".deeeedddd." - /* 6 */ ".deeeedddd." - /* 7 */ ".ddddddddd." - /* 8 */ "..fffffff.." - /* 9 */ "mmfffffffmm" - /* 10 */ "mmfffffffmm" - /* 11 */ "mmfffffffmm" - /* 12 */ "mmfffffffmm" + /* z\x* 012345678 */ + /* 0 */ "aaaaaaaaa" + /* 1 */ "aaaaaaaaa" + /* 2 */ "aaaaaaaaa" + /* 3 */ "aaaaaaaaa" + /* 4 */ "aaaaaaaaa" + /* 5 */ "aaaaaaaaa" + /* 6 */ "aaaaaaaaa" + /* 7 */ "aaaaaaaaa" + /* 8 */ "aaaaaaaaa" + /* 9 */ "aaaaaaaaa" + /* 10 */ "aaaaaaaaa" + /* 11 */ "aaaaaaaaa" + /* 12 */ "aaaaaaaaa" // Level 1 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".ghhhihhhg." - /* 2 */ ".h.e....jh." - /* 3 */ ".h.e....kh." - /* 4 */ ".h.e....lh." - /* 5 */ ".h.......h." - /* 6 */ ".h.......h." - /* 7 */ ".ghhhihhhg." - /* 8 */ "..k.....k.." - /* 9 */ "mmk.....kmm" - /* 10 */ "mmk.....kmm" - /* 11 */ "mmk.....kmm" - /* 12 */ "mmkkkkkkkmm" + /* z\x* 012345678 */ + /* 0 */ "bbbbbbbbb" + /* 1 */ "bbbbbbbbb" + /* 2 */ "bbbbbbbbb" + /* 3 */ "bbbbbbbbb" + /* 4 */ "baaaaabbb" + /* 5 */ "baaaaaabb" + /* 6 */ "baaaaaabb" + /* 7 */ "baaaaaabb" + /* 8 */ "baaaaabbb" + /* 9 */ "bbbbbbbbb" + /* 10 */ "bbbbbbbbb" + /* 11 */ "bbbbbbbbb" + /* 12 */ "bbbbbbbbb" // Level 2 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".gnnhohnng." - /* 2 */ ".n.......n." - /* 3 */ ".n......pn." - /* 4 */ ".h.......h." - /* 5 */ ".n.......n." - /* 6 */ ".n.......n." - /* 7 */ ".gnnhohnng." - /* 8 */ "..........." - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm" + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".ccccc..." + /* 5 */ ".cccccd.." + /* 6 */ ".ccccce.." + /* 7 */ ".cccccf.." + /* 8 */ ".ccccc..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." // Level 3 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "lllllllllll" - /* 1 */ "qhhhhhhhhhq" - /* 2 */ ".h.......h." - /* 3 */ ".h.......h." - /* 4 */ ".hr.....sh." - /* 5 */ ".h.......h." - /* 6 */ ".h.......h." - /* 7 */ "thhhhhhhhht" - /* 8 */ "jjjjjjjjjjj" - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm" + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".ghhhg..." + /* 5 */ ".h...h..." + /* 6 */ ".hij.k..." + /* 7 */ ".h...h..." + /* 8 */ ".ghhhg..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." // Level 4 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "lllllllllll" - /* 2 */ "qhhhhhhhhhq" - /* 3 */ ".h.......h." - /* 4 */ ".h.......h." - /* 5 */ ".h.......h." - /* 6 */ "thhhhhhhhht" - /* 7 */ "jjjjjjjjjjj" - /* 8 */ "..........." - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm" + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".glllg..." + /* 5 */ ".l...h..." + /* 6 */ ".l.n.o..." + /* 7 */ ".l...h..." + /* 8 */ ".glllg..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." // Level 5 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "lllllllllll" - /* 3 */ "qhhhhhhhhhq" - /* 4 */ ".h.......h." - /* 5 */ "thhhhhhhhht" - /* 6 */ "jjjjjjjjjjj" - /* 7 */ "..........." - /* 8 */ "..........." - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm" + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".ghhhg..." + /* 5 */ ".h..ph..." + /* 6 */ ".h.n.h..." + /* 7 */ ".h..ph..n" + /* 8 */ ".ghhhg..q" + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." // Level 6 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "..........." - /* 3 */ "lllllllllll" - /* 4 */ "hhhhhhhhhhh" - /* 5 */ "jjjjjjjjjjj" - /* 6 */ "..........." - /* 7 */ "..........." - /* 8 */ "..........." - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm", + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".grrrg..." + /* 5 */ ".s...s..." + /* 6 */ ".s.n.s..." + /* 7 */ ".s...s..n" + /* 8 */ ".grrrg..q" + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 7 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".ghhhg..." + /* 5 */ ".h...h..." + /* 6 */ ".h.n.h..n" + /* 7 */ ".h...h..q" + /* 8 */ ".ghhhg..q" + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 8 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "........." + /* 4 */ ".glllg..." + /* 5 */ ".l...l..." + /* 6 */ ".l.n.l..n" + /* 7 */ ".l...l..q" + /* 8 */ ".glllg..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 9 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.q" + /* 1 */ "mmmmmmm.q" + /* 2 */ "mmmmmmm.q" + /* 3 */ "........." + /* 4 */ ".ghhhg..." + /* 5 */ ".h...h..n" + /* 6 */ ".h.n.h..q" + /* 7 */ ".h...h..q" + /* 8 */ ".ghhhg..." + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 10 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.n" + /* 1 */ "mmmmmmm.n" + /* 2 */ "mmmmmmm.q" + /* 3 */ "........q" + /* 4 */ ".grrrg..q" + /* 5 */ ".s...s..n" + /* 6 */ ".s.n.s..q" + /* 7 */ ".s...s..n" + /* 8 */ ".grrrg..n" + /* 9 */ "........." + /* 10 */ "mmmmmmm.." + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 11 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.n" + /* 3 */ "ttttttt.n" + /* 4 */ "uhhhhhu.q" + /* 5 */ ".h...h..q" + /* 6 */ ".h.nrrrrr" + /* 7 */ ".h...h..q" + /* 8 */ "vhhhhhv.q" + /* 9 */ "wwwwwww.n" + /* 10 */ "mmmmmmm.n" + /* 11 */ "mmmmmmm.." + /* 12 */ "mmmmmmm.." + + // Level 12 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "mmmmmmm.." + /* 4 */ "ttttttt.n" + /* 5 */ "uhhhhhu.n" + /* 6 */ ".h...h..q" + /* 7 */ "vhhhhhv.n" + /* 8 */ "wwwwwww.q" + /* 9 */ "mmmmmmm.q" + /* 10 */ "mmmmmmm.q" + /* 11 */ "mmmmmmm.n" + /* 12 */ "mmmmmmm.n" + + // Level 13 + /* z\x* 012345678 */ + /* 0 */ "mmmmmmm.." + /* 1 */ "mmmmmmm.." + /* 2 */ "mmmmmmm.." + /* 3 */ "mmmmmmm.." + /* 4 */ "mmmmmmm.." + /* 5 */ "ttttttt.q" + /* 6 */ "hhhhhhh.q" + /* 7 */ "wwwwwww.n" + /* 8 */ "mmmmmmm.." + /* 9 */ "mmmmmmm.." + /* 10 */ "mmmmmmm.q" + /* 11 */ "mmmmmmm.q" + /* 12 */ "mmmmmmm.q" + + // Level 14 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." + /* 3 */ "........." + /* 4 */ "........." + /* 5 */ "........q" + /* 6 */ "........n" + /* 7 */ "........." + /* 8 */ "........." + /* 9 */ "........." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." + + // Level 15 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." + /* 3 */ "........." + /* 4 */ "........q" + /* 5 */ "........q" + /* 6 */ "........n" + /* 7 */ "........." + /* 8 */ "........." + /* 9 */ "........." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." + + // Level 16 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." + /* 3 */ "........." + /* 4 */ "........q" + /* 5 */ "........n" + /* 6 */ "........." + /* 7 */ "........." + /* 8 */ "........." + /* 9 */ "........." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." + + // Level 17 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." + /* 3 */ "........." + /* 4 */ "........q" + /* 5 */ "........n" + /* 6 */ "........." + /* 7 */ "........." + /* 8 */ "........." + /* 9 */ "........." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ ".........", // Connectors: - "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 8, 2, 6: 5\n" /* Type -1, direction X+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -3048,7 +3797,342 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, - }, // PlainsVillage_99 + }, // WoodenMill5x5 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // WoodenStables: + // The data has been exported from the gallery Plains, area index 55, ID 106, created by Aloe_vera + { + // Size: + 15, 10, 9, // SizeX = 15, SizeY = 10, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 14, 9, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 3: 0\n" /* dirt */ + "b: 2: 0\n" /* grass */ + "c: 67: 0\n" /* stairs */ + "d: 67: 2\n" /* stairs */ + "e: 67: 1\n" /* stairs */ + "f: 4: 0\n" /* cobblestone */ + "g: 17: 0\n" /* tree */ + "h:107: 0\n" /* fencegate */ + "i:107: 4\n" /* fencegate */ + "j: 5: 0\n" /* wood */ + "k:107: 6\n" /* fencegate */ + "l: 85: 0\n" /* fence */ + "m: 19: 0\n" /* sponge */ + "n:170: 0\n" /* haybale */ + "o:170: 4\n" /* haybale */ + "p:170: 8\n" /* haybale */ + "q: 50: 1\n" /* torch */ + "r: 50: 2\n" /* torch */ + "s: 53: 2\n" /* woodstairs */ + "t: 53: 7\n" /* woodstairs */ + "u: 53: 6\n" /* woodstairs */ + "v: 53: 3\n" /* woodstairs */, + + // 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 */ "baaaaaaaaaaaaab" + /* 1 */ "baaaaaaaaaaaaab" + /* 2 */ "baaaaaaaaaaaaab" + /* 3 */ "baaaaaaaaaaaaab" + /* 4 */ "baaaaaaaaaaaaab" + /* 5 */ "baaaaaaaaaaaaab" + /* 6 */ "baaaaaaaaaaaaab" + /* 7 */ "baaaaaaaaaaaaab" + /* 8 */ "bbbbbbbbbbbbbbb" + + // Level 2 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ ".cddddddddddde." + /* 1 */ ".fffffffffffff." + /* 2 */ ".faaaaaaaaaaaf." + /* 3 */ ".faaaaaaaaaaaf." + /* 4 */ ".faaaaaaaaaaaf." + /* 5 */ ".faaaaaaaaaaaf." + /* 6 */ ".faaaaaaaaaaaf." + /* 7 */ ".fffffffffffff." + /* 8 */ "..............." + + // Level 3 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".ghihjhihjhkhg." + /* 2 */ ".l...l...l...l." + /* 3 */ ".l...l...l...l." + /* 4 */ ".l...l...l...l." + /* 5 */ ".l...l...l...l." + /* 6 */ ".ln..l..olp..l." + /* 7 */ ".gllljllljlllg." + /* 8 */ "..............." + + // Level 4 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".g...j...j...g." + /* 2 */ "..............." + /* 3 */ "..............." + /* 4 */ "..............." + /* 5 */ "..............." + /* 6 */ "..............." + /* 7 */ ".g...j...j...g." + /* 8 */ "..............." + + // Level 5 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".gq.rjq.rjq.rg." + /* 2 */ "..............." + /* 3 */ "..............." + /* 4 */ "..............." + /* 5 */ "..............." + /* 6 */ "..............." + /* 7 */ ".g...j...j...g." + /* 8 */ "..............." + + // Level 6 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "sssssssssssssss" + /* 1 */ "tjjjjjjjjjjjjjt" + /* 2 */ ".j...........j." + /* 3 */ ".j...........j." + /* 4 */ ".j...........j." + /* 5 */ ".j...........j." + /* 6 */ ".j...........j." + /* 7 */ "ujjjjjjjjjjjjju" + /* 8 */ "vvvvvvvvvvvvvvv" + + // Level 7 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "sssssssssssssss" + /* 2 */ "tjjjjjjjjjjjjjt" + /* 3 */ ".j...........j." + /* 4 */ ".j...........j." + /* 5 */ ".j...........j." + /* 6 */ "ujjjjjjjjjjjjju" + /* 7 */ "vvvvvvvvvvvvvvv" + /* 8 */ "..............." + + // Level 8 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "..............." + /* 2 */ "sssssssssssssss" + /* 3 */ "tjjjjjjjjjjjjjt" + /* 4 */ ".j...........j." + /* 5 */ "ujjjjjjjjjjjjju" + /* 6 */ "vvvvvvvvvvvvvvv" + /* 7 */ "..............." + /* 8 */ "..............." + + // Level 9 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "..............." + /* 2 */ "..............." + /* 3 */ "sssssssssssssss" + /* 4 */ "jjjjjjjjjjjjjjj" + /* 5 */ "vvvvvvvvvvvvvvv" + /* 6 */ "..............." + /* 7 */ "..............." + /* 8 */ "...............", + + // Connectors: + "-1: 7, 2, -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, + }, // 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, + }, // CobbleWell4x4 @@ -3234,7 +4318,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 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 */ @@ -3254,466 +4341,6 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, }, // RoofedWell - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Windmill: - // The data has been exported from the gallery Plains, area index 60, ID 111, created by Aloe_vera - { - // Size: - 9, 16, 13, // SizeX = 9, SizeY = 16, SizeZ = 13 - - // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 8, 15, 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 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "........." - /* 4 */ ".aaaaa..." - /* 5 */ ".aaaaab.." - /* 6 */ ".aaaaac.." - /* 7 */ ".aaaaad.." - /* 8 */ ".aaaaa..." - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 1 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "........." - /* 4 */ ".efffe..." - /* 5 */ ".f...f..." - /* 6 */ ".fgh.i..." - /* 7 */ ".f...f..." - /* 8 */ ".efffe..." - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 2 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "........." - /* 4 */ ".ejjje..." - /* 5 */ ".j...f..." - /* 6 */ ".j.k.l..." - /* 7 */ ".j...f..." - /* 8 */ ".ejjje..." - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 3 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "........." - /* 4 */ ".efffe..." - /* 5 */ ".f..nf..." - /* 6 */ ".f.k.f..." - /* 7 */ ".f..nf..k" - /* 8 */ ".efffe..o" - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 4 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "........." - /* 4 */ ".epppe..." - /* 5 */ ".q...q..." - /* 6 */ ".q.k.q..." - /* 7 */ ".q...q..k" - /* 8 */ ".epppe..o" - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 5 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "........." - /* 4 */ ".efffe..." - /* 5 */ ".f...f..." - /* 6 */ ".f.k.f..k" - /* 7 */ ".f...f..o" - /* 8 */ ".efffe..o" - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 6 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "........." - /* 4 */ ".ejjje..." - /* 5 */ ".j...j..." - /* 6 */ ".j.k.j..k" - /* 7 */ ".j...j..o" - /* 8 */ ".ejjje..." - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 7 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.o" - /* 1 */ "mmmmmmm.o" - /* 2 */ "mmmmmmm.o" - /* 3 */ "........." - /* 4 */ ".efffe..." - /* 5 */ ".f...f..k" - /* 6 */ ".f.k.f..o" - /* 7 */ ".f...f..o" - /* 8 */ ".efffe..." - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 8 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.k" - /* 1 */ "mmmmmmm.k" - /* 2 */ "mmmmmmm.o" - /* 3 */ "........o" - /* 4 */ ".epppe..o" - /* 5 */ ".q...q..k" - /* 6 */ ".q.k.q..o" - /* 7 */ ".q...q..k" - /* 8 */ ".epppe..k" - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 9 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.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 */ "mmmmmmm.k" - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." - - // Level 10 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "mmmmmmm.." - /* 4 */ "rrrrrrr.k" - /* 5 */ "sfffffs.k" - /* 6 */ ".f...f..o" - /* 7 */ "tffffft.k" - /* 8 */ "uuuuuuu.o" - /* 9 */ "mmmmmmm.o" - /* 10 */ "mmmmmmm.o" - /* 11 */ "mmmmmmm.k" - /* 12 */ "mmmmmmm.k" - - // Level 11 - /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "mmmmmmm.." - /* 4 */ "mmmmmmm.." - /* 5 */ "rrrrrrr.o" - /* 6 */ "fffffff.o" - /* 7 */ "uuuuuuu.k" - /* 8 */ "mmmmmmm.." - /* 9 */ "mmmmmmm.." - /* 10 */ "mmmmmmm.o" - /* 11 */ "mmmmmmm.o" - /* 12 */ "mmmmmmm.o" - - // Level 12 - /* z\x* 012345678 */ - /* 0 */ "........." - /* 1 */ "........." - /* 2 */ "........." - /* 3 */ "........." - /* 4 */ "........." - /* 5 */ "........o" - /* 6 */ "........k" - /* 7 */ "........." - /* 8 */ "........." - /* 9 */ "........." - /* 10 */ "........." - /* 11 */ "........." - /* 12 */ "........." - - // Level 13 - /* z\x* 012345678 */ - /* 0 */ "........." - /* 1 */ "........." - /* 2 */ "........." - /* 3 */ "........." - /* 4 */ "........o" - /* 5 */ "........o" - /* 6 */ "........k" - /* 7 */ "........." - /* 8 */ "........." - /* 9 */ "........." - /* 10 */ "........." - /* 11 */ "........." - /* 12 */ "........." - - // Level 14 - /* z\x* 012345678 */ - /* 0 */ "........." - /* 1 */ "........." - /* 2 */ "........." - /* 3 */ "........." - /* 4 */ "........o" - /* 5 */ "........k" - /* 6 */ "........." - /* 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 */ ".........", - - // Connectors: - "-1: 5, 0, 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, - }, // Windmill -}; // g_PlainsVillagePrefabs - - - - - - -const cPrefab::sDef g_PlainsVillageStartingPrefabs[] = -{ - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Well: - // 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, - }, // Well }; From 8bb8c2ca7ded71f57ec83ebc8a5214d01ae0b9b7 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 17 May 2014 13:04:40 +0100 Subject: [PATCH 057/312] Don't start mcserver up in coverage builds Starting the server up is not a test. --- CIbuild.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CIbuild.sh b/CIbuild.sh index 20785a488..683c1fc74 100755 --- a/CIbuild.sh +++ b/CIbuild.sh @@ -6,4 +6,6 @@ cmake . -DBUILD_TOOLS=1 -DSELF_TEST=1; make -j 2; make -j 2 test; cd MCServer/; -echo stop | $MCSERVER_PATH; +if [ "$TRAVIS_MCSERVER_BUILD_TYPE" != "COVERAGE" ] + then echo stop | $MCSERVER_PATH; +fi From 029e9a826a763e32496c30f259301c9d2d357a5f Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 17 May 2014 13:05:12 +0100 Subject: [PATCH 058/312] test code does not need testing --- uploadCoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index fc17ddc2c..7b3195fce 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -3,7 +3,7 @@ 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 + coveralls --exclude lib --exclude Android --exclude tests >/dev/null fi From 46971330755be516b189601eea10c274ed918319 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 17 May 2014 13:20:28 +0100 Subject: [PATCH 059/312] excluding tests excludes everything --- uploadCoverage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uploadCoverage.sh b/uploadCoverage.sh index 7b3195fce..fc17ddc2c 100755 --- a/uploadCoverage.sh +++ b/uploadCoverage.sh @@ -3,7 +3,7 @@ if [ "$TRAVIS_MCSERVER_BUILD_TYPE" == "COVERAGE" ] then find tests -type f -name '*.gcda' -exec sh -c 'cp {} $(dirname {})/../$(basename {})' \; - coveralls --exclude lib --exclude Android --exclude tests >/dev/null + coveralls --exclude lib --exclude Android >/dev/null fi From 710656f84f7a572ff92a302548b19d1705c66851 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 17 May 2014 13:39:28 +0100 Subject: [PATCH 060/312] Rewrote array copies test Moved each patten test into its own scope to test all unallocated section code paths. Moved 0's around so that they test the allocated sections code paths. --- tests/ChunkBuffer/Copies.cpp | 111 ++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 48 deletions(-) diff --git a/tests/ChunkBuffer/Copies.cpp b/tests/ChunkBuffer/Copies.cpp index b37414ce4..76af81496 100644 --- a/tests/ChunkBuffer/Copies.cpp +++ b/tests/ChunkBuffer/Copies.cpp @@ -33,6 +33,21 @@ int main(int argc, char** argv) delete DstBlockBuffer; SrcBlockBuffer = NULL; DstBlockBuffer = NULL; + + SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); + buffer.SetBlocks(SrcBlockBuffer); + DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + buffer.CopyBlocks(DstBlockBuffer); + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); + delete SrcBlockBuffer; + delete DstBlockBuffer; + SrcBlockBuffer = NULL; + DstBlockBuffer = NULL; + + } + { + cChunkBuffer buffer; NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) @@ -51,54 +66,7 @@ int main(int argc, char** argv) delete DstNibbleBuffer; SrcNibbleBuffer = NULL; DstNibbleBuffer = NULL; - - SrcNibbleBuffer = new NIBBLETYPE[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.SetLight(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; - - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) - { - SrcNibbleBuffer[i+0] = 0xAD; - SrcNibbleBuffer[i+1] = 0xBE; - SrcNibbleBuffer[i+2] = 0xEF; - SrcNibbleBuffer[i+3] = 0xDE; - } - - buffer.SetSkyLight(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopySkyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; - - SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; - memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); - buffer.SetBlocks(SrcBlockBuffer); - DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; - buffer.CopyBlocks(DstBlockBuffer); - testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); - delete SrcBlockBuffer; - delete DstBlockBuffer; - SrcBlockBuffer = NULL; - DstBlockBuffer = NULL; - + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); buffer.SetMeta(SrcNibbleBuffer); @@ -110,6 +78,28 @@ int main(int argc, char** argv) SrcNibbleBuffer = NULL; DstNibbleBuffer = NULL; + } + { + cChunkBuffer buffer; + + NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[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.SetLight(SrcNibbleBuffer); + NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); buffer.SetLight(SrcNibbleBuffer); @@ -121,6 +111,30 @@ int main(int argc, char** argv) SrcNibbleBuffer = NULL; DstNibbleBuffer = NULL; + + } + { + cChunkBuffer buffer; + + NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) + { + SrcNibbleBuffer[i+0] = 0xAD; + SrcNibbleBuffer[i+1] = 0xBE; + SrcNibbleBuffer[i+2] = 0xEF; + SrcNibbleBuffer[i+3] = 0xDE; + } + + buffer.SetSkyLight(SrcNibbleBuffer); + NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + buffer.CopySkyLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); + delete SrcNibbleBuffer; + delete DstNibbleBuffer; + SrcNibbleBuffer = NULL; + DstNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); buffer.SetSkyLight(SrcNibbleBuffer); @@ -131,6 +145,7 @@ int main(int argc, char** argv) delete DstNibbleBuffer; SrcNibbleBuffer = NULL; DstNibbleBuffer = NULL; + } { cChunkBuffer buffer; From a7a811af3a2b7d4425abca2c7b4d733ab75449f6 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 17 May 2014 13:59:31 +0100 Subject: [PATCH 061/312] Add tests for assignment operator --- tests/ChunkBuffer/Coordinates.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/ChunkBuffer/Coordinates.cpp b/tests/ChunkBuffer/Coordinates.cpp index b9861df23..d4fca1e50 100644 --- a/tests/ChunkBuffer/Coordinates.cpp +++ b/tests/ChunkBuffer/Coordinates.cpp @@ -120,5 +120,16 @@ int main(int argc, char** argv) } + { + // Operator = + cChunkBuffer buffer; + buffer.SetBlock(0,0,0,0x42); + cChunkBuffer copy; + copy = buffer; + testassert(copy.GetBlock(0,0,0) == 0x42); + copy = copy; + testassert(copy.GetBlock(0,0,0) == 0x42) + } + return 0; } From 7777da379d35b10bee38b2faf218810552452130 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 17 May 2014 14:04:44 +0100 Subject: [PATCH 062/312] Fix assignment operators --- src/ChunkBuffer.h | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h index e16575bb2..1f170abba 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -53,21 +53,25 @@ public: other.IsOwner = false; } - void operator=(const cChunkBuffer& other) + cChunkBuffer& operator=(const cChunkBuffer& other) { - if(IsOwner) + if(&other == this) { + if(IsOwner) + { + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + if(m_Sections[i]) Free(m_Sections[i]);; + } + } + IsOwner = true; for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i]) Free(m_Sections[i]);; + m_Sections[i] = other.m_Sections[i]; } + other.IsOwner = false; } - IsOwner = true; - for (int i = 0; i < CHUNK_SECTION_NUM; i++) - { - m_Sections[i] = other.m_Sections[i]; - } - other.IsOwner = false; + } #else // unique_ptr style interface for memory management @@ -79,7 +83,7 @@ public: } } - void operator=(const cChunkBuffer&& other) + cChunkBuffer& operator=(const cChunkBuffer&& other) { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { From d53c84a7811e7f7af144efe24fdc21fa7b07f6ce Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 17 May 2014 14:07:49 +0100 Subject: [PATCH 063/312] Add test for zeros --- tests/ChunkBuffer/ArraytoCoord.cpp | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/ChunkBuffer/ArraytoCoord.cpp b/tests/ChunkBuffer/ArraytoCoord.cpp index a765c5302..993dc6cc5 100644 --- a/tests/ChunkBuffer/ArraytoCoord.cpp +++ b/tests/ChunkBuffer/ArraytoCoord.cpp @@ -7,6 +7,7 @@ int main(int argc, char** argv) { { + // Test first segment cChunkBuffer buffer; BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; @@ -43,6 +44,7 @@ int main(int argc, char** argv) } { + // test following segment cChunkBuffer buffer; BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; @@ -77,5 +79,38 @@ int main(int argc, char** argv) delete SrcNibbleBuffer; SrcNibbleBuffer = NULL; } + + { + // test zeros + cChunkBuffer buffer; + + BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); + buffer.SetBlocks(SrcBlockBuffer); + testassert(buffer.GetBlock(7,24,4) == 0x00); + delete SrcBlockBuffer; + SrcBlockBuffer = NULL; + + NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + buffer.SetMeta(SrcNibbleBuffer); + testassert(buffer.GetMeta(6,24,1) == 0x0); + delete SrcNibbleBuffer; + SrcNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + buffer.SetLight(SrcNibbleBuffer); + testassert(buffer.GetBlockLight(6,24,1) == 0x0); + delete SrcNibbleBuffer; + SrcNibbleBuffer = NULL; + + SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + buffer.SetSkyLight(SrcNibbleBuffer); + testassert(buffer.GetSkyLight(6,24,1) == 0xF); + delete SrcNibbleBuffer; + SrcNibbleBuffer = NULL; + } } From 4e841146b89523b0fe3f8f75b75c97a29b194e21 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 17 May 2014 14:29:15 +0100 Subject: [PATCH 064/312] Fix assignment ops 2 --- src/ChunkBuffer.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h index 1f170abba..66edce867 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -71,6 +71,7 @@ public: } other.IsOwner = false; } + return *this; } #else @@ -85,11 +86,15 @@ public: cChunkBuffer& operator=(const cChunkBuffer&& other) { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + if(&other != this) { - if(m_Sections[i]) Free(m_Sections[i]);; - m_Sections[i] = other.m_Sections[i]; + for (int i = 0; i < CHUNK_SECTION_NUM; i++) + { + if(m_Sections[i]) Free(m_Sections[i]);; + m_Sections[i] = other.m_Sections[i]; + } } + return *this; } #endif From 7616895eb32a90715c3a4c7762c23f0a10605db3 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sat, 17 May 2014 14:35:08 +0100 Subject: [PATCH 065/312] Fix assignment operators test --- tests/ChunkBuffer/Coordinates.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ChunkBuffer/Coordinates.cpp b/tests/ChunkBuffer/Coordinates.cpp index d4fca1e50..9eb30fa0a 100644 --- a/tests/ChunkBuffer/Coordinates.cpp +++ b/tests/ChunkBuffer/Coordinates.cpp @@ -125,10 +125,10 @@ int main(int argc, char** argv) cChunkBuffer buffer; buffer.SetBlock(0,0,0,0x42); cChunkBuffer copy; - copy = buffer; + copy = std::move(buffer); + testassert(copy.GetBlock(0,0,0) == 0x42); + copy = std::move(copy); testassert(copy.GetBlock(0,0,0) == 0x42); - copy = copy; - testassert(copy.GetBlock(0,0,0) == 0x42) } return 0; From 1f98f21dd1c1664102dfb480a69c8d1901c3ae5f Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 17 May 2014 15:11:58 +0100 Subject: [PATCH 066/312] fixed assignment bugs and Skylight bug --- src/ChunkBuffer.h | 8 +++++--- tests/ChunkBuffer/ArraytoCoord.cpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h index 66edce867..4086c4ae9 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -76,15 +76,16 @@ public: } #else // unique_ptr style interface for memory management - cChunkBuffer(const cChunkBuffer&& other) + cChunkBuffer(cChunkBuffer&& other) { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { m_Sections[i] = other.m_Sections[i]; + other.m_Sections[i] = 0; } } - cChunkBuffer& operator=(const cChunkBuffer&& other) + cChunkBuffer& operator=(cChunkBuffer&& other) { if(&other != this) { @@ -92,6 +93,7 @@ public: { if(m_Sections[i]) Free(m_Sections[i]);; m_Sections[i] = other.m_Sections[i]; + other.m_Sections[i] = 0; } } return *this; @@ -230,7 +232,7 @@ public: } else { - return 0xFF; + return 0xF; } } ASSERT(!"cChunkBuffer::GetMeta(): coords out of chunk range!"); diff --git a/tests/ChunkBuffer/ArraytoCoord.cpp b/tests/ChunkBuffer/ArraytoCoord.cpp index 993dc6cc5..5563a3f86 100644 --- a/tests/ChunkBuffer/ArraytoCoord.cpp +++ b/tests/ChunkBuffer/ArraytoCoord.cpp @@ -106,7 +106,7 @@ int main(int argc, char** argv) SrcNibbleBuffer = NULL; SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); buffer.SetSkyLight(SrcNibbleBuffer); testassert(buffer.GetSkyLight(6,24,1) == 0xF); delete SrcNibbleBuffer; From 016b8f7b993624a96f040e5d1b5e8564369b62f7 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 17 May 2014 15:19:35 +0100 Subject: [PATCH 067/312] C++11 --- tests/ChunkBuffer/Coordinates.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/ChunkBuffer/Coordinates.cpp b/tests/ChunkBuffer/Coordinates.cpp index 9eb30fa0a..bed61d5dc 100644 --- a/tests/ChunkBuffer/Coordinates.cpp +++ b/tests/ChunkBuffer/Coordinates.cpp @@ -125,9 +125,17 @@ int main(int argc, char** argv) cChunkBuffer buffer; buffer.SetBlock(0,0,0,0x42); cChunkBuffer copy; + #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); } From f451075c1f60dbea9521113269cc8e69e0730841 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 17 May 2014 15:32:28 +0100 Subject: [PATCH 068/312] derp --- src/ChunkBuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h index 4086c4ae9..bd178beaa 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -55,7 +55,7 @@ public: cChunkBuffer& operator=(const cChunkBuffer& other) { - if(&other == this) + if(&other != this) { if(IsOwner) { From 7004043c6164c6b22346f94489cb823f9495738f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 17 May 2014 21:54:04 +0200 Subject: [PATCH 069/312] Village houses are height-adjusted onto the terrain. --- src/Generating/PieceGenerator.cpp | 11 +++++++++ src/Generating/PieceGenerator.h | 7 ++++++ src/Generating/Prefab.cpp | 12 +++++++-- src/Generating/Prefab.h | 3 +++ src/Generating/VillageGen.cpp | 41 +++++++++++++++++++++++++++---- 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index ce19c1c95..c12559d3f 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -297,6 +297,17 @@ 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); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPieceGenerator: diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 16bec3bb4..56ce996d2 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -144,6 +144,13 @@ public: const cCuboid & GetHitBox (void) const { return m_HitBox; } int GetDepth (void) const { return m_Depth; } + /** 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; + protected: const cPlacedPiece * m_Parent; const cPiece * m_Piece; diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 9aef7a94b..506e1c2cc 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -191,13 +191,21 @@ void cPrefab::AddRotatedBlockAreas(void) 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) diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index c08413e87..2b89a204c 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -94,6 +94,9 @@ public: /** 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; diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index b514a90cd..db81fb521 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -115,7 +115,9 @@ public: m_HeightGen(a_HeightGen) { cBFSPieceGenerator pg(m_Prefabs, a_Seed); - pg.PlacePieces(a_OriginX, 10, a_OriginZ, a_MaxRoadDepth + 1, m_Pieces); + // Generate the pieces at very negative Y coords, so that we can later test + // Piece has negative Y coord -> hasn't been height-adjusted yet + pg.PlacePieces(a_OriginX, -1000, a_OriginZ, a_MaxRoadDepth + 1, m_Pieces); } protected: @@ -144,16 +146,45 @@ protected: // cGrdStructGen::cStructure overrides: virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override { - // TODO // Iterate over all items - // Each intersecting prefab is placed on ground (if not already placed), then drawn + // Each intersecting prefab is placed on ground, then drawn // Each intersecting road is drawn by replacing top soil blocks with gravel / sandstone blocks - for (cPlacedPieces::const_iterator itr = m_Pieces.begin(), end = m_Pieces.end(); itr != end; ++itr) + 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) { - const cPrefab & Prefab = (const cPrefab &)((*itr)->GetPiece()); + cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece()); + if ((*itr)->GetPiece().GetSize().y == 1) + { + // It's a road, special handling (change top terrain blocks + // TODO + Prefab.Draw(a_Chunk, (*itr)->GetCoords() + Vector3i(0, 1100, 0), (*itr)->GetNumCCWRotations()); + continue; + } + if ((*itr)->GetCoords().y < 0) + { + 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.GetCoords().y += TerrainHeight - FirstConnector.m_Pos.y + 1; + } } ; From a7e52e51dc3665ac2c2f27ed52e732ef7bbad32e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 17 May 2014 22:26:09 +0200 Subject: [PATCH 070/312] Village roads are drawn properly. --- src/Generating/PieceGenerator.h | 4 ++-- src/Generating/VillageGen.cpp | 39 ++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 56ce996d2..643ca58b6 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -156,8 +156,8 @@ protected: 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 }; typedef std::vector cPlacedPieces; diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index db81fb521..520d63029 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -104,7 +104,8 @@ public: int a_MaxRoadDepth, int a_MaxSize, cPrefabPiecePool & a_Prefabs, - cTerrainHeightGen & a_HeightGen + cTerrainHeightGen & a_HeightGen, + BLOCKTYPE a_RoadBlock ) : super(a_OriginX, a_OriginZ), m_Seed(a_Seed), @@ -112,7 +113,8 @@ public: m_MaxSize(a_MaxSize), 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_HeightGen(a_HeightGen), + m_RoadBlock(a_RoadBlock) { cBFSPieceGenerator pg(m_Prefabs, a_Seed); // Generate the pieces at very negative Y coords, so that we can later test @@ -142,6 +144,9 @@ protected: /** The village pieces, placed by the generator. */ cPlacedPieces m_Pieces; + /** The block to use for the roads. */ + BLOCKTYPE m_RoadBlock; + // cGrdStructGen::cStructure overrides: virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override @@ -156,9 +161,8 @@ protected: cPrefab & Prefab = (cPrefab &)((*itr)->GetPiece()); if ((*itr)->GetPiece().GetSize().y == 1) { - // It's a road, special handling (change top terrain blocks - // TODO - Prefab.Draw(a_Chunk, (*itr)->GetCoords() + Vector3i(0, 1100, 0), (*itr)->GetNumCCWRotations()); + // It's a road, special handling (change top terrain blocks to m_RoadBlock) + DrawRoad(a_Chunk, **itr, HeightMap); continue; } if ((*itr)->GetCoords().y < 0) @@ -185,6 +189,27 @@ protected: int TerrainHeight = cChunkDef::GetHeight(HeightMap, BlockX, BlockZ); a_Piece.GetCoords().y += 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++) + { + a_Chunk.SetBlockType(x, cChunkDef::GetHeight(a_HeightMap, x, z), z, m_RoadBlock); + } + } + } } ; @@ -228,6 +253,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ // 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; for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++) { switch (Biomes[i]) @@ -237,6 +263,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ { // These biomes allow sand villages VillagePrefabs = &g_SandVillage; + RoadBlock = E_BLOCK_SANDSTONE; break; } case biPlains: @@ -261,7 +288,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ { return cStructurePtr(); } - return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, *VillagePrefabs, m_HeightGen)); + return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, *VillagePrefabs, m_HeightGen, RoadBlock)); } From 8a0d3f79219a324c11930c8f22763f34e16a96f6 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 18 May 2014 15:10:12 +0100 Subject: [PATCH 071/312] Fixed issue with types not being defined for an unused parameter --- src/BlockArea.h | 1 + src/ChunkBuffer.h | 63 ---------------- src/ChunkDataCallback.h | 105 ++++++++++++++++++++++++++ src/ChunkDef.h | 40 ---------- src/ChunkMap.h | 3 +- src/ChunkSender.h | 2 +- src/WorldStorage/NBTChunkSerializer.h | 2 +- src/WorldStorage/WSSCompact.h | 2 +- 8 files changed, 111 insertions(+), 107 deletions(-) create mode 100644 src/ChunkDataCallback.h diff --git a/src/BlockArea.h b/src/BlockArea.h index 50c28aaf2..9c01719c3 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -14,6 +14,7 @@ #include "ForEachChunkProvider.h" #include "Vector3.h" +#include "ChunkDataCallback.h" diff --git a/src/ChunkBuffer.h b/src/ChunkBuffer.h index bd178beaa..266df2332 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkBuffer.h @@ -275,68 +275,5 @@ private: -/** A simple implementation of the cChunkDataCallback interface that collects all block data into a buffer -*/ -class cChunkBufferCollector : - public cChunkDataCallback -{ -public: - - cChunkBuffer m_BlockData; - -protected: - - virtual void ChunkBuffer(const cChunkBuffer & 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 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 ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override - { - a_ChunkBuffer.CopyBlocks(m_BlockData); - a_ChunkBuffer.CopyMeta(m_BlockData + cChunkDef::NumBlocks); - a_ChunkBuffer.CopyLight(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 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 ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override - { - a_ChunkBuffer.CopyBlocks(m_BlockTypes); - a_ChunkBuffer.CopyMeta(m_BlockMetas); - a_ChunkBuffer.CopyLight(m_BlockLight); - a_ChunkBuffer.CopySkyLight(m_BlockSkyLight); - } -} ; - - diff --git a/src/ChunkDataCallback.h b/src/ChunkDataCallback.h new file mode 100644 index 000000000..76c45040e --- /dev/null +++ b/src/ChunkDataCallback.h @@ -0,0 +1,105 @@ + + +#pragma once + + +#include "ChunkBuffer.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 ChunkBuffer (const cChunkBuffer & 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 cChunkBufferCollector : + public cChunkDataCallback +{ +public: + + cChunkBuffer m_BlockData; + +protected: + + virtual void ChunkBuffer(const cChunkBuffer & 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 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 ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override + { + a_ChunkBuffer.CopyBlocks(m_BlockData); + a_ChunkBuffer.CopyMeta(m_BlockData + cChunkDef::NumBlocks); + a_ChunkBuffer.CopyLight(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 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 ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override + { + a_ChunkBuffer.CopyBlocks(m_BlockTypes); + a_ChunkBuffer.CopyMeta(m_BlockMetas); + a_ChunkBuffer.CopyLight(m_BlockLight); + a_ChunkBuffer.CopySkyLight(m_BlockSkyLight); + } +} ; + diff --git a/src/ChunkDef.h b/src/ChunkDef.h index d79f4b92b..f89e16ed1 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -328,46 +328,6 @@ private: -class cChunkBuffer; - - -/** 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 ChunkBuffer (const cChunkBuffer & 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); }; -} ; - - - /** Interface class used for comparing clients of two chunks. diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 9d973f2a9..c3deda088 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -5,7 +5,8 @@ #pragma once -#include "ChunkDef.h" + +#include "ChunkDataCallback.h" diff --git a/src/ChunkSender.h b/src/ChunkSender.h index 81b298a55..00565d7c3 100644 --- a/src/ChunkSender.h +++ b/src/ChunkSender.h @@ -27,7 +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 "ChunkBuffer.h" +#include "ChunkDataCallback.h" diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 6da2bc6dd..112afc27e 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -9,7 +9,7 @@ #pragma once -#include "../ChunkBuffer.h" +#include "ChunkDataCallback.h" diff --git a/src/WorldStorage/WSSCompact.h b/src/WorldStorage/WSSCompact.h index 606853a16..6c363d5ac 100644 --- a/src/WorldStorage/WSSCompact.h +++ b/src/WorldStorage/WSSCompact.h @@ -14,7 +14,7 @@ #include "WorldStorage.h" #include "../Vector3.h" #include "json/json.h" -#include "ChunkBuffer.h" +#include "ChunkDataCallback.h" From ec50c0f9e1ee59ad8e782795c46f100be79b3ed0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 18 May 2014 23:09:39 +0200 Subject: [PATCH 072/312] Updated SandVillage prefabs to latest Gallery content. This fixes sand village generation. --- src/Generating/Prefabs/SandVillagePrefabs.cpp | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Generating/Prefabs/SandVillagePrefabs.cpp b/src/Generating/Prefabs/SandVillagePrefabs.cpp index 8460ee5f7..539f57b9d 100644 --- a/src/Generating/Prefabs/SandVillagePrefabs.cpp +++ b/src/Generating/Prefabs/SandVillagePrefabs.cpp @@ -183,7 +183,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 6 */ "...........", // Connectors: - "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -326,7 +326,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ "...........", // Connectors: - "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -444,7 +444,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 6 */ ".............", // Connectors: - "-1: 6, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 6, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -587,7 +587,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ ".............", // Connectors: - "-1: 6, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 6, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -730,7 +730,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ "...............", // Connectors: - "-1: 6, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 6, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -873,7 +873,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ "................", // Connectors: - "-1: 9, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 9, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -984,7 +984,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 6 */ ".......", // Connectors: - "-1: 4, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1096,7 +1096,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 6 */ ".........", // Connectors: - "-1: 4, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1232,7 +1232,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 8 */ ".........", // Connectors: - "-1: 4, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 4, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1384,7 +1384,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 11 */ "mmmmmmm..adc..", // Connectors: - "-1: 8, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 8, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1552,7 +1552,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 11 */ "mmmmm...adc...", // Connectors: - "-1: 5, 0, 1: 2\n" /* Type -1, direction Z- */, + "-1: 5, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1712,7 +1712,7 @@ const cPrefab::sDef g_SandVillagePrefabs[] = /* 5 */ ".....", // Connectors: - "-1: 2, 0, 4: 3\n" /* Type -1, direction Z+ */, + "-1: 2, 0, 5: 3\n" /* Type -1, direction Z+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ From cfbb2563604e77e044be9a0f12b2152a7d626b51 Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Mon, 19 May 2014 10:37:43 +0200 Subject: [PATCH 073/312] Fixed some warnings --- Tools/MCADefrag/Globals.h | 1 + src/Simulator/IncrementalRedstoneSimulator.h | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Tools/MCADefrag/Globals.h b/Tools/MCADefrag/Globals.h index 0f31de7e3..17dc3920d 100644 --- a/Tools/MCADefrag/Globals.h +++ b/Tools/MCADefrag/Globals.h @@ -225,6 +225,7 @@ template 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/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index 233a3d408..a57a17328 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -202,8 +202,13 @@ private: case E_BLOCK_POWERED_RAIL: { return true; + break; + } + default: + { + return false; + break; } - default: return false; } } @@ -275,8 +280,13 @@ private: case E_BLOCK_PISTON: { return true; + break; + } + default: + { + return false; + break; } - default: return false; } } }; From e9abf9a4987835a52dab508f9b8a8feb57e9a103 Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Mon, 19 May 2014 13:02:02 +0200 Subject: [PATCH 074/312] Rolled some changes back --- src/Simulator/IncrementalRedstoneSimulator.h | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index a57a17328..233a3d408 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -202,13 +202,8 @@ private: case E_BLOCK_POWERED_RAIL: { return true; - break; - } - default: - { - return false; - break; } + default: return false; } } @@ -280,13 +275,8 @@ private: case E_BLOCK_PISTON: { return true; - break; - } - default: - { - return false; - break; } + default: return false; } } }; From fb7f2993bf3b62c00d4502b846018b035ffbdb7a Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Mon, 19 May 2014 14:34:34 +0200 Subject: [PATCH 075/312] Fixed some warnings in Server.cpp, and in UI/ --- src/Server.cpp | 8 +++++++- src/UI/SlotArea.cpp | 3 ++- src/UI/Window.cpp | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) 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/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 8833a767a..be3ce1f8d 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -600,7 +600,8 @@ cCraftingRecipe & cSlotAreaCrafting::GetRecipeForPlayer(cPlayer & a_Player) cSlotAreaAnvil::cSlotAreaAnvil(cAnvilWindow & a_ParentWindow) : cSlotAreaTemporary(3, a_ParentWindow), - m_MaximumCost(0) + m_MaximumCost(0), + m_StackSizeToBeUsedInRepair(0) { } diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 46885390b..24b718156 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -856,7 +856,8 @@ cEnchantingWindow::cEnchantingWindow(int a_BlockX, int a_BlockY, int a_BlockZ) : cWindow(wtEnchantment, "Enchant"), m_BlockX(a_BlockX), m_BlockY(a_BlockY), - m_BlockZ(a_BlockZ) + m_BlockZ(a_BlockZ), + m_SlotArea() { m_SlotAreas.push_back(new cSlotAreaEnchanting(*this)); m_SlotAreas.push_back(new cSlotAreaInventory(*this)); From 6687848a7ec1a65ed2c99264ecf9e8119b19c964 Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Mon, 19 May 2014 14:49:18 +0200 Subject: [PATCH 076/312] Fixed warnings in IncrementalRedstoneSimulator --- src/Simulator/IncrementalRedstoneSimulator.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 074063add..8d29fbec7 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -18,7 +18,13 @@ cIncrementalRedstoneSimulator::cIncrementalRedstoneSimulator(cWorld & a_World) - : super(a_World) + : super(a_World), + m_RedstoneSimulatorChunkData(), + m_PoweredBlocks(), + m_LinkedPoweredBlocks(), + m_SimulatedPlayerToggleableBlocks(), + m_RepeatersDelayList(), + m_Chunk() { } From 7e2effb2d8297ddb99d86844e1b06b37c6e30d63 Mon Sep 17 00:00:00 2001 From: Julian Laubstein Date: Mon, 19 May 2014 15:46:36 +0200 Subject: [PATCH 077/312] Changed the m_slotarea position --- src/UI/Window.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index 24b718156..98a9a0cec 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -854,10 +854,10 @@ 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), - m_SlotArea() + m_BlockZ(a_BlockZ) { m_SlotAreas.push_back(new cSlotAreaEnchanting(*this)); m_SlotAreas.push_back(new cSlotAreaInventory(*this)); From 42c36429d7cd1e6c3f879b6749e18e912deefe0d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 19 May 2014 20:40:56 +0100 Subject: [PATCH 078/312] Added client translation to achievements --- src/CompositeChat.cpp | 22 ++++++++++++++++++++++ src/CompositeChat.h | 15 +++++++++++++++ src/Entities/Player.cpp | 8 ++++---- src/Protocol/Protocol17x.cpp | 29 +++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index c70ef1070..d3b7595b7 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -189,6 +189,15 @@ void cCompositeChat::AddSuggestCommandPart(const AString & a_Text, const AString +void cCompositeChat::AddShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style) +{ + m_Parts.push_back(new cShowAchievementPart(a_PlayerName, a_Achievement, a_Style)); +} + + + + + void cCompositeChat::ParseText(const AString & a_ParseText) { size_t len = a_ParseText.length(); @@ -476,3 +485,16 @@ cCompositeChat::cSuggestCommandPart::cSuggestCommandPart(const AString & a_Text, + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cCompositeChat::cShowAchievementPart: + +cCompositeChat::cShowAchievementPart::cShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style) : + super(ptShowAchievement, a_Achievement, a_Style), + m_PlayerName(a_PlayerName) +{ +} + + + + diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 5b9c5f612..a0264d864 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -38,6 +38,7 @@ public: ptUrl, ptRunCommand, ptSuggestCommand, + ptShowAchievement, } ; class cBasePart @@ -106,6 +107,15 @@ public: public: cSuggestCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = ""); } ; + + class cShowAchievementPart : + public cBasePart + { + typedef cBasePart super; + public: + AString m_PlayerName; + cShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style = ""); + } ; typedef std::vector cParts; @@ -148,6 +158,11 @@ public: /** Adds a part that suggests a command (enters it into the chat message area, but doesn't send) when clicked. The default style is underlined yellow text. */ void AddSuggestCommandPart(const AString & a_Text, const AString & a_SuggestedCommand, const AString & a_Style = "u@b"); + + /** Adds a part that fully formats a specified achievement using client translatable strings + Takes achievement name and player awarded to. Displays as {player} has earned the achievement {achievement_name}. + */ + void AddShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style = ""); /** Parses text into various parts, adds those. Recognizes "http:" and "https:" URLs and @color-codes. */ diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c3b763278..3a32bfb2e 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1169,8 +1169,8 @@ unsigned int cPlayer::AwardAchievement(const eStatistic a_Ach) { // First time, announce it cCompositeChat Msg; - Msg.AddTextPart(m_PlayerName + " has just earned the achievement "); - Msg.AddTextPart(cStatInfo::GetName(a_Ach)); // TODO 2014-05-12 xdot: Use the proper cCompositeChat part (cAchievement) + Msg.SetMessageType(mtSuccess); + Msg.AddShowAchievementPart(GetName(), cStatInfo::GetName(a_Ach)); m_World->BroadcastChat(Msg); // Increment the statistic @@ -1788,7 +1788,7 @@ bool cPlayer::SaveToDisk() // Save the player stats. // We use the default world name (like bukkit) because stats are shared between dimensions/worlds. - cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), m_PlayerName, &m_Stats); + cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), GetName(), &m_Stats); if (!StatSerializer.Save()) { LOGERROR("Could not save stats for player %s", m_PlayerName.c_str()); @@ -1963,7 +1963,7 @@ void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos) BLOCKTYPE Block; NIBBLETYPE Meta; - if (!m_World->GetBlockTypeMeta(PosX, PosY, PosZ, Block, Meta)) + if ((PosY < 0) || (PosY > cChunkDef::Height) || !m_World->GetBlockTypeMeta(PosX, PosY, PosZ, Block, Meta)) { return; } diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 39feee16f..3061d132b 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -289,6 +289,35 @@ void cProtocol172::SendChat(const cCompositeChat & a_Message) AddChatPartStyle(Part, p.m_Style); break; } + + case cCompositeChat::ptShowAchievement: + { + const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr; + Part["translate"] = "chat.type.achievement"; + + Json::Value Ach; + Ach["action"] = "show_achievement"; + Ach["value"] = p.m_Text; + + Json::Value AchColourAndName; + AchColourAndName["color"] = "green"; + AchColourAndName["translate"] = p.m_Text; + AchColourAndName["hoverEvent"] = Ach; + + Json::Value Extra; + Extra.append(AchColourAndName); + + Json::Value Name; + Name["text"] = p.m_PlayerName; + + Json::Value With; + With.append(Name); + With.append(Extra); + + Part["with"] = With; + AddChatPartStyle(Part, p.m_Style); + break; + } } msg["extra"].append(Part); } // for itr - Parts[] From 3a9543178abb7500aff65e09f054c28200ca6cac Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 19 May 2014 21:16:29 +0100 Subject: [PATCH 079/312] cCompositeChat message type is now formatted --- src/ClientHandle.h | 4 ++-- src/CompositeChat.cpp | 3 ++- src/CompositeChat.h | 9 ++++++++- src/Protocol/Protocol17x.cpp | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 9f1245be5..659c67658 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -80,9 +80,9 @@ public: static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export /** Formats the type of message with the proper color and prefix for sending to the client. **/ - AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData); + static AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData); - AString FormatChatPrefix(bool ShouldAppendChatPrefixes, AString a_ChatPrefixS, AString m_Color1, AString m_Color2); + static AString FormatChatPrefix(bool ShouldAppendChatPrefixes, AString a_ChatPrefixS, AString m_Color1, AString m_Color2); void Kick(const AString & a_Reason); // tolua_export void Authenticate(const AString & a_Name, const AString & a_UUID); // Called by cAuthenticator when the user passes authentication diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index d3b7595b7..a3612983a 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -299,9 +299,10 @@ void cCompositeChat::ParseText(const AString & a_ParseText) -void cCompositeChat::SetMessageType(eMessageType a_MessageType) +void cCompositeChat::SetMessageType(eMessageType a_MessageType, const AString & a_AdditionalMessageTypeData) { m_MessageType = a_MessageType; + m_AdditionalMessageTypeData = a_AdditionalMessageTypeData; } diff --git a/src/CompositeChat.h b/src/CompositeChat.h index a0264d864..209d9d925 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -47,6 +47,7 @@ public: ePartType m_PartType; AString m_Text; AString m_Style; + AString m_AdditionalStyleData; cBasePart(ePartType a_PartType, const AString & a_Text, const AString & a_Style = ""); @@ -169,7 +170,7 @@ public: void ParseText(const AString & a_ParseText); /** Sets the message type, which is indicated by prefixes added to the message when serializing. */ - void SetMessageType(eMessageType a_MessageType); + void SetMessageType(eMessageType a_MessageType, const AString & a_AdditionalMessageTypeata = ""); /** Adds the "underline" style to each part that is an URL. */ void UnderlineUrls(void); @@ -178,6 +179,9 @@ public: /** Returns the message type set previously by SetMessageType(). */ eMessageType GetMessageType(void) const { return m_MessageType; } + + /** Returns additional data pertaining to message type, for example, the name of a mtPrivateMsg sender */ + AString GetAdditionalMessageTypeData(void) const { return m_AdditionalMessageTypeData; } /** Returns the text from the parts that comprises the human-readable data. Used for older protocols that don't support composite chat @@ -199,6 +203,9 @@ protected: /** The message type, as indicated by prefixes. */ eMessageType m_MessageType; + /** Additional data pertaining to message type, for example, the name of a mtPrivateMsg sender */ + AString m_AdditionalMessageTypeData; + /** Adds a_AddStyle to a_Style; overwrites the existing style if appropriate. If the style already contains something that a_AddStyle overrides, it is erased first. */ diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 3061d132b..7c526d103 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -234,7 +234,7 @@ void cProtocol172::SendChat(const cCompositeChat & a_Message) // Compose the complete Json string to send: Json::Value msg; - msg["text"] = ""; // The client crashes without this + msg["text"] = cClientHandle::FormatMessageType(m_Client->GetPlayer()->GetWorld()->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) { From 4008af692556ffb0f819c9a570267ffbaa871cad Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 19 May 2014 21:17:28 +0100 Subject: [PATCH 080/312] Simplified cacti conditions --- src/Entities/Entity.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 15f456332..ed06e76b9 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1024,9 +1024,9 @@ void cEntity::DetectCacti() float w = m_Width / 2; if ( (((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) || - (((GetPosX() - (X - 1)) - 1 < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) || + ((GetPosX() - X < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) || (((Z + 1) - GetPosZ() < w) && (GetWorld()->GetBlock(X, Y, Z + 1) == E_BLOCK_CACTUS)) || - (((GetPosZ() - (Z - 1)) - 1 < w) && (GetWorld()->GetBlock(X, Y, Z - 1) == E_BLOCK_CACTUS)) || + ((GetPosZ() - Z < w) && (GetWorld()->GetBlock(X, Y, Z - 1) == E_BLOCK_CACTUS)) || (((Y > 0) && (Y < cChunkDef::Height)) && ((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y, Z) == E_BLOCK_CACTUS))) ) { From 2bfe962e2831316f651aa22c4e7b7ea68021c978 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 19 May 2014 22:15:39 +0100 Subject: [PATCH 081/312] Fixed a cactus Y position issue --- src/Entities/Entity.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index ed06e76b9..8a584d2ca 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1023,11 +1023,12 @@ void cEntity::DetectCacti() int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; float w = m_Width / 2; if ( - (((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) || + ((Y > 0) && (Y < cChunkDef::Height)) && + ((((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) || ((GetPosX() - X < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) || (((Z + 1) - GetPosZ() < w) && (GetWorld()->GetBlock(X, Y, Z + 1) == E_BLOCK_CACTUS)) || ((GetPosZ() - Z < w) && (GetWorld()->GetBlock(X, Y, Z - 1) == E_BLOCK_CACTUS)) || - (((Y > 0) && (Y < cChunkDef::Height)) && ((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y, Z) == E_BLOCK_CACTUS))) + (((GetPosY() - Y < 1) && (GetWorld()->GetBlock(X, Y, Z) == E_BLOCK_CACTUS)))) ) { TakeDamage(dtCactusContact, NULL, 1, 0); From 507df718453483e6ca74ca897a78eed679222f06 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Tue, 20 May 2014 13:35:39 +0100 Subject: [PATCH 082/312] Update Player.cpp --- src/Entities/Player.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 3a32bfb2e..c27456397 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -377,7 +377,7 @@ short cPlayer::DeltaExperience(short a_Xp_delta) } LOGD("Player \"%s\" gained/lost %d experience, total is now: %d", - m_PlayerName.c_str(), a_Xp_delta, m_CurrentXp); + GetName().c_str(), a_Xp_delta, m_CurrentXp); // Set experience to be updated m_bDirtyExperience = true; @@ -391,7 +391,7 @@ short cPlayer::DeltaExperience(short a_Xp_delta) void cPlayer::StartChargingBow(void) { - LOGD("Player \"%s\" started charging their bow", m_PlayerName.c_str()); + LOGD("Player \"%s\" started charging their bow", GetName().c_str()); m_IsChargingBow = true; m_BowCharge = 0; } @@ -402,7 +402,7 @@ void cPlayer::StartChargingBow(void) int cPlayer::FinishChargingBow(void) { - LOGD("Player \"%s\" finished charging their bow at a charge of %d", m_PlayerName.c_str(), m_BowCharge); + LOGD("Player \"%s\" finished charging their bow at a charge of %d", GetName().c_str(), m_BowCharge); int res = m_BowCharge; m_IsChargingBow = false; m_BowCharge = 0; @@ -415,7 +415,7 @@ int cPlayer::FinishChargingBow(void) void cPlayer::CancelChargingBow(void) { - LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", m_PlayerName.c_str(), m_BowCharge); + LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", GetName().c_str(), m_BowCharge); m_IsChargingBow = false; m_BowCharge = 0; } @@ -1305,7 +1305,7 @@ void cPlayer::AddToGroup( const AString & a_GroupName ) { cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName ); m_Groups.push_back( Group ); - LOGD("Added %s to group %s", m_PlayerName.c_str(), a_GroupName.c_str() ); + LOGD("Added %s to group %s", GetName().c_str(), a_GroupName.c_str() ); ResolveGroups(); ResolvePermissions(); } @@ -1329,13 +1329,13 @@ void cPlayer::RemoveFromGroup( const AString & a_GroupName ) if( bRemoved ) { - LOGD("Removed %s from group %s", m_PlayerName.c_str(), a_GroupName.c_str() ); + LOGD("Removed %s from group %s", GetName().c_str(), a_GroupName.c_str() ); ResolveGroups(); ResolvePermissions(); } else { - LOGWARN("Tried to remove %s from group %s but was not in that group", m_PlayerName.c_str(), a_GroupName.c_str() ); + LOGWARN("Tried to remove %s from group %s but was not in that group", GetName().c_str(), a_GroupName.c_str() ); } } @@ -1441,7 +1441,7 @@ void cPlayer::ResolveGroups() if( AllGroups.find( CurrentGroup ) != AllGroups.end() ) { LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!", - m_PlayerName.c_str(), CurrentGroup->GetName().c_str() + GetName().c_str(), CurrentGroup->GetName().c_str() ); } else @@ -1453,7 +1453,7 @@ void cPlayer::ResolveGroups() { if( AllGroups.find( *itr ) != AllGroups.end() ) { - LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", m_PlayerName.c_str(), (*itr)->GetName().c_str() ); + LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", GetName().c_str(), (*itr)->GetName().c_str() ); continue; } ToIterate.push_back( *itr ); @@ -1605,19 +1605,19 @@ void cPlayer::LoadPermissionsFromDisk() cIniFile IniFile; if (IniFile.ReadFile("users.ini")) { - AString Groups = IniFile.GetValueSet(m_PlayerName, "Groups", "Default"); + AString Groups = IniFile.GetValueSet(GetName(), "Groups", "Default"); AStringVector Split = StringSplitAndTrim(Groups, ","); for (AStringVector::const_iterator itr = Split.begin(), end = Split.end(); itr != end; ++itr) { if (!cRoot::Get()->GetGroupManager()->ExistsGroup(*itr)) { - LOGWARNING("The group %s for player %s was not found!", itr->c_str(), m_PlayerName.c_str()); + LOGWARNING("The group %s for player %s was not found!", itr->c_str(), GetName().c_str()); } AddToGroup(*itr); } - AString Color = IniFile.GetValue(m_PlayerName, "Color", "-"); + AString Color = IniFile.GetValue(GetName(), "Color", "-"); if (!Color.empty()) { m_Color = Color[0]; @@ -1626,7 +1626,7 @@ void cPlayer::LoadPermissionsFromDisk() else { cGroupManager::GenerateDefaultUsersIni(IniFile); - IniFile.AddValue("Groups", m_PlayerName, "Default"); + IniFile.AddValue("Groups", GetName(), "Default"); AddToGroup("Default"); } IniFile.WriteFile("users.ini"); @@ -1641,14 +1641,14 @@ bool cPlayer::LoadFromDisk() LoadPermissionsFromDisk(); // Log player permissions, cause it's what the cool kids do - LOGINFO("Player %s has permissions:", m_PlayerName.c_str() ); + 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", m_PlayerName.c_str() ); + Printf(SourceFile, "players/%s.json", GetName().c_str() ); cFile f; if (!f.Open(SourceFile, cFile::fmRead)) @@ -1716,7 +1716,7 @@ bool cPlayer::LoadFromDisk() StatSerializer.Load(); LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"", - m_PlayerName.c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str() + GetName().c_str(), GetPosX(), GetPosY(), GetPosZ(), m_LoadedWorldName.c_str() ); return true; @@ -1772,12 +1772,12 @@ bool cPlayer::SaveToDisk() std::string JsonData = writer.write(root); AString SourceFile; - Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); + Printf(SourceFile, "players/%s.json", GetName().c_str() ); cFile f; if (!f.Open(SourceFile, cFile::fmWrite)) { - LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", m_PlayerName.c_str(), SourceFile.c_str()); + LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", GetName().c_str(), SourceFile.c_str()); return false; } if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size()) @@ -1791,7 +1791,7 @@ bool cPlayer::SaveToDisk() cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), GetName(), &m_Stats); if (!StatSerializer.Save()) { - LOGERROR("Could not save stats for player %s", m_PlayerName.c_str()); + LOGERROR("Could not save stats for player %s", GetName().c_str()); return false; } From 07baf9bdd3b04e3aec6e77f367eb38c0547f54ca Mon Sep 17 00:00:00 2001 From: andrew Date: Tue, 20 May 2014 15:52:59 +0300 Subject: [PATCH 083/312] Cleaned up cPlayer::UpdateMovementStats; Wither achievements --- src/Blocks/BlockMobHead.h | 27 +++++++++++++++ src/Entities/Player.cpp | 71 ++++++++++++++++++++++++++++++-------- src/Entities/Player.h | 3 ++ src/Items/ItemFishingRod.h | 6 ++++ src/Mobs/Wither.cpp | 33 ++++++++++++++++++ src/Mobs/Wither.h | 1 + src/Statistics.cpp | 2 +- 7 files changed, 128 insertions(+), 15 deletions(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index acd1c88fb..552c0491c 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -46,8 +46,29 @@ public: bool IsWither(void) const { return m_IsWither; } void Reset(void) { m_IsWither = false; } + } CallbackA, CallbackB; + class cPlayerCallback : public cPlayerListCallback + { + Vector3f m_Pos; + + virtual bool Item(cPlayer * a_Player) + { + double Dist = (a_Player->GetPosition() - m_Pos).Length(); + if (Dist < 50.0) + { + // If player is close, award achievement + a_Player->AwardAchievement(achSpawnWither); + } + return false; + } + + public: + cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {} + + } PlayerCallback(Vector3f(a_BlockX, a_BlockY, a_BlockZ)); + a_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA); if (!CallbackA.IsWither()) @@ -86,6 +107,9 @@ public: // Spawn the wither: a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + // Award Achievement + a_World->ForEachPlayer(PlayerCallback); + return true; } @@ -113,6 +137,9 @@ public: // Spawn the wither: a_World->SpawnMob(a_BlockX + 0.5, a_BlockY - 2, a_BlockZ + 0.5, cMonster::mtWither); + // Award Achievement + a_World->ForEachPlayer(PlayerCallback); + return true; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index c3b763278..0eacb67f9 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -456,8 +456,18 @@ void cPlayer::SetTouchGround(bool a_bTouchGround) else { float Dist = (float)(m_LastGroundHeight - floor(GetPosY())); + + if (Dist >= 2.0) // At least two blocks - TODO: Use m_LastJumpHeight instead of m_LastGroundHeight above + { + // Increment statistic + m_Stats.AddValue(statDistFallen, (StatValue)floor(Dist * 100 + 0.5)); + } + int Damage = (int)(Dist - 3.f); - if (m_LastJumpHeight > m_LastGroundHeight) Damage++; + if (m_LastJumpHeight > m_LastGroundHeight) + { + Damage++; + } m_LastJumpHeight = (float)GetPosY(); if (Damage > 0) @@ -1951,31 +1961,64 @@ void cPlayer::HandleFloater() +bool cPlayer::IsClimbing(void) const +{ + int PosX = POSX_TOINT; + int PosY = POSY_TOINT; + int PosZ = POSZ_TOINT; + + if ((PosY < 0) || (PosY >= cChunkDef::Height)) + { + return false; + } + + BLOCKTYPE Block = m_World->GetBlock(PosX, PosY, PosZ); + switch (Block) + { + case E_BLOCK_LADDER: + case E_BLOCK_VINES: + { + return true; + } + default: return false; + } +} + + + + + void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos) { StatValue Value = (StatValue)floor(a_DeltaPos.Length() * 100 + 0.5); if (m_AttachedTo == NULL) { - int PosX = POSX_TOINT; - int PosY = POSY_TOINT; - int PosZ = POSZ_TOINT; - - BLOCKTYPE Block; - NIBBLETYPE Meta; - if (!m_World->GetBlockTypeMeta(PosX, PosY, PosZ, Block, Meta)) + if (IsClimbing()) { - return; + if (a_DeltaPos.y > 0.0) // Going up + { + m_Stats.AddValue(statDistClimbed, (StatValue)floor(a_DeltaPos.y * 100 + 0.5)); + } } - - if ((Block == E_BLOCK_LADDER) && (a_DeltaPos.y > 0.0)) // Going up + else if (IsSubmerged()) { - m_Stats.AddValue(statDistClimbed, (StatValue)floor(a_DeltaPos.y * 100 + 0.5)); + m_Stats.AddValue(statDistDove, Value); + } + else if (IsSwimming()) + { + m_Stats.AddValue(statDistSwum, Value); + } + else if (IsOnGround()) + { + m_Stats.AddValue(statDistWalked, Value); } else { - // TODO 2014-05-12 xdot: Other types - m_Stats.AddValue(statDistWalked, Value); + if (Value >= 25) // Ignore small/slow movement + { + m_Stats.AddValue(statDistFlown, Value); + } } } else diff --git a/src/Entities/Player.h b/src/Entities/Player.h index 78b534d83..b7cb27d6c 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -127,6 +127,9 @@ public: inline const cItem & GetEquippedItem(void) const { return GetInventory().GetEquippedItem(); } // tolua_export + /** Returns whether the player is climbing (ladders, vines e.t.c). */ + bool IsClimbing(void) const; + virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) override; // tolua_begin diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h index 0431b88b7..32c151db5 100644 --- a/src/Items/ItemFishingRod.h +++ b/src/Items/ItemFishingRod.h @@ -142,6 +142,8 @@ public: break; } } + + a_Player->GetStatManager().AddValue(statTreasureFished, 1); } else if (ItemCategory <= 14) // Junk 10% { @@ -190,6 +192,8 @@ public: { Drops.Add(cItem(E_BLOCK_TRIPWIRE_HOOK)); } + + a_Player->GetStatManager().AddValue(statJunkFished, 1); } else // Fish { @@ -210,6 +214,8 @@ public: { Drops.Add(cItem(E_ITEM_RAW_FISH, 1, E_META_RAW_FISH_FISH)); } + + a_Player->GetStatManager().AddValue(statFishCaught, 1); } if (cRoot::Get()->GetPluginManager()->CallHookPlayerFishing(*a_Player, Drops)) diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index 5b6e895e1..deb2cf34e 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -2,7 +2,9 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Wither.h" + #include "../World.h" +#include "../Entities/Player.h" @@ -100,3 +102,34 @@ void cWither::GetDrops(cItems & a_Drops, cEntity * a_Killer) + +void cWither::KilledBy(cEntity * a_Killer) +{ + UNUSED(a_Killer); + + class cPlayerCallback : public cPlayerListCallback + { + Vector3f m_Pos; + + virtual bool Item(cPlayer * a_Player) + { + double Dist = (a_Player->GetPosition() - m_Pos).Length(); + if (Dist < 50.0) + { + // If player is close, award achievement + a_Player->AwardAchievement(achKillWither); + } + return false; + } + + public: + cPlayerCallback(const Vector3f & a_Pos) : m_Pos(a_Pos) {} + + } PlayerCallback(GetPosition()); + + m_World->ForEachPlayer(PlayerCallback); +} + + + + diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index 08b460009..93b4f8bfc 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -29,6 +29,7 @@ public: 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; + virtual void KilledBy(cEntity * a_Killer) override; private: diff --git a/src/Statistics.cpp b/src/Statistics.cpp index 5950eb96c..5c0524f9e 100644 --- a/src/Statistics.cpp +++ b/src/Statistics.cpp @@ -52,7 +52,7 @@ cStatInfo cStatInfo::ms_Info[statCount] = { /* Type | Name */ cStatInfo(statGamesQuit, "stat.leaveGame"), cStatInfo(statMinutesPlayed, "stat.playOneMinute"), - cStatInfo(statDistWalked, "stat.walkOnCm"), + cStatInfo(statDistWalked, "stat.walkOneCm"), cStatInfo(statDistSwum, "stat.swimOneCm"), cStatInfo(statDistFallen, "stat.fallOneCm"), cStatInfo(statDistClimbed, "stat.climbOneCm"), From 576e17ae08ddd0dcff625134325bfceeab956906 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 20 May 2014 22:49:21 +0100 Subject: [PATCH 084/312] Update CompositeChat.h --- src/CompositeChat.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 209d9d925..1ad196f1d 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -169,8 +169,10 @@ public: Recognizes "http:" and "https:" URLs and @color-codes. */ void ParseText(const AString & a_ParseText); - /** Sets the message type, which is indicated by prefixes added to the message when serializing. */ - void SetMessageType(eMessageType a_MessageType, const AString & a_AdditionalMessageTypeata = ""); + /** Sets the message type, which is indicated by prefixes added to the message when serializing + Takes optional AdditionalMessageTypeData to set m_AdditionalMessageTypeData. See said variable for more documentation. + */ + void SetMessageType(eMessageType a_MessageType, const AString & a_AdditionalMessageTypeData = ""); /** Adds the "underline" style to each part that is an URL. */ void UnderlineUrls(void); From 7aeb8ce9936e8ebd203d67100de8635d391bd8a1 Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 21 May 2014 10:59:14 +0300 Subject: [PATCH 085/312] Fixed cWither::KilledBy --- src/Blocks/BlockMobHead.h | 1 + src/Mobs/Wither.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 552c0491c..b7629b07c 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -55,6 +55,7 @@ public: virtual bool Item(cPlayer * a_Player) { + // TODO 2014-05-21 xdot: Vanilla minecraft uses an AABB check instead of a radius one double Dist = (a_Player->GetPosition() - m_Pos).Length(); if (Dist < 50.0) { diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index deb2cf34e..170f4fdc0 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -105,7 +105,7 @@ void cWither::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cWither::KilledBy(cEntity * a_Killer) { - UNUSED(a_Killer); + super::KilledBy(a_Killer); class cPlayerCallback : public cPlayerListCallback { @@ -113,6 +113,7 @@ void cWither::KilledBy(cEntity * a_Killer) virtual bool Item(cPlayer * a_Player) { + // TODO 2014-05-21 xdot: Vanilla minecraft uses an AABB check instead of a radius one double Dist = (a_Player->GetPosition() - m_Pos).Length(); if (Dist < 50.0) { From cdd3d11496d51ce6f444a2e637fee1d38e07fd09 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 21 May 2014 18:33:54 +0100 Subject: [PATCH 086/312] Fixed minor style issues --- MCServer/Plugins/Core | 2 +- src/BlockArea.cpp | 2 +- src/BlockArea.h | 4 ++-- src/Chunk.cpp | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 013a32a7f..5c8557d4f 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 013a32a7fb3c8a6cfe0aef892d4c7394d4e1be59 +Subproject commit 5c8557d4fdfa580c100510cde07a1a778ea2e244 diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index fd2f3c9b4..5e41b135c 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -1843,7 +1843,7 @@ void cBlockArea::cChunkReader::ChunkBuffer(const cChunkBuffer & a_BlockBuffer) 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; diff --git a/src/BlockArea.h b/src/BlockArea.h index 9c01719c3..6b3bdf337 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -317,8 +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 ChunkBuffer (const cChunkBuffer & a_BlockTypes) override; + virtual bool Coords(int a_ChunkX, int a_ChunkZ) override; + virtual void ChunkBuffer(const cChunkBuffer & a_BlockTypes) override; } ; typedef NIBBLETYPE * NIBBLEARRAY; diff --git a/src/Chunk.cpp b/src/Chunk.cpp index a986ac076..00ea33e16 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -282,10 +282,10 @@ void cChunk::SetAllData( CalculateHeightmap(a_BlockTypes); } - m_ChunkBuffer.SetBlocks (a_BlockTypes); - m_ChunkBuffer.SetMeta (a_BlockMeta); - m_ChunkBuffer.SetLight (a_BlockLight); - m_ChunkBuffer.SetSkyLight (a_BlockSkyLight); + m_ChunkBuffer.SetBlocks(a_BlockTypes); + m_ChunkBuffer.SetMeta(a_BlockMeta); + m_ChunkBuffer.SetLight(a_BlockLight); + m_ChunkBuffer.SetSkyLight(a_BlockSkyLight); m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL); From 024027db89ca833406147b79b7be74fc92906bbe Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 21 May 2014 19:58:48 +0100 Subject: [PATCH 087/312] Renamed cChunkBuffer to cChunkData --- src/BlockArea.cpp | 4 +- src/BlockArea.h | 2 +- src/Chunk.cpp | 38 +++++++++---------- src/Chunk.h | 12 +++--- src/{ChunkBuffer.cpp => ChunkData.cpp} | 30 +++++++-------- src/{ChunkBuffer.h => ChunkData.h} | 26 ++++++------- src/ChunkDataCallback.h | 18 ++++----- src/LightingThread.cpp | 2 +- src/WorldStorage/WSSCompact.h | 2 +- tests/CMakeLists.txt | 2 +- .../ArraytoCoord.cpp | 8 ++-- .../{ChunkBuffer => ChunkData}/CMakeLists.txt | 2 +- .../Coordinates.cpp | 10 ++--- tests/{ChunkBuffer => ChunkData}/Copies.cpp | 14 +++---- .../{ChunkBuffer => ChunkData}/creatable.cpp | 4 +- 15 files changed, 87 insertions(+), 87 deletions(-) rename src/{ChunkBuffer.cpp => ChunkData.cpp} (88%) rename src/{ChunkBuffer.h => ChunkData.h} (91%) rename tests/{ChunkBuffer => ChunkData}/ArraytoCoord.cpp (97%) rename tests/{ChunkBuffer => ChunkData}/CMakeLists.txt (91%) rename tests/{ChunkBuffer => ChunkData}/Coordinates.cpp (95%) rename tests/{ChunkBuffer => ChunkData}/Copies.cpp (97%) rename tests/{ChunkBuffer => ChunkData}/creatable.cpp (61%) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 5e41b135c..0c46e59e5 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 "ChunkBuffer.h" +#include "ChunkData.h" @@ -1835,7 +1835,7 @@ bool cBlockArea::cChunkReader::Coords(int a_ChunkX, int a_ChunkZ) -void cBlockArea::cChunkReader::ChunkBuffer(const cChunkBuffer & a_BlockBuffer) +void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) { { if (!(m_Area.m_BlockTypes == NULL)) diff --git a/src/BlockArea.h b/src/BlockArea.h index 6b3bdf337..2bd26facd 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -318,7 +318,7 @@ protected: // cChunkDataCallback overrides: virtual bool Coords(int a_ChunkX, int a_ChunkZ) override; - virtual void ChunkBuffer(const cChunkBuffer & a_BlockTypes) override; + virtual void ChunkData(const cChunkData & a_BlockTypes) override; } ; typedef NIBBLETYPE * NIBBLEARRAY; diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 00ea33e16..a45ed32c1 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -238,12 +238,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); - a_Callback.LightIsValid (m_IsLightValid); + a_Callback.LightIsValid(m_IsLightValid); - a_Callback.ChunkBuffer (m_ChunkBuffer); + a_Callback.ChunkData(m_ChunkData); for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr) { @@ -282,10 +282,10 @@ void cChunk::SetAllData( CalculateHeightmap(a_BlockTypes); } - m_ChunkBuffer.SetBlocks(a_BlockTypes); - m_ChunkBuffer.SetMeta(a_BlockMeta); - m_ChunkBuffer.SetLight(a_BlockLight); - m_ChunkBuffer.SetSkyLight(a_BlockSkyLight); + m_ChunkData.SetBlocks(a_BlockTypes); + m_ChunkData.SetMeta(a_BlockMeta); + m_ChunkData.SetLight(a_BlockLight); + m_ChunkData.SetSkyLight(a_BlockSkyLight); m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL); @@ -326,9 +326,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 :) - m_ChunkBuffer.SetLight (a_BlockLight); + m_ChunkData.SetLight (a_BlockLight); - m_ChunkBuffer.SetSkyLight (a_SkyLight); + m_ChunkData.SetSkyLight (a_SkyLight); m_IsLightValid = true; } @@ -339,7 +339,7 @@ void cChunk::SetLight( void cChunk::GetBlockTypes(BLOCKTYPE * a_BlockTypes) { - m_ChunkBuffer.CopyBlocks(a_BlockTypes); + m_ChunkData.CopyBlocks(a_BlockTypes); } @@ -1507,7 +1507,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT ASSERT(IsValid()); const BLOCKTYPE OldBlockType = GetBlock(a_RelX, a_RelY, a_RelZ); - const BLOCKTYPE OldBlockMeta = m_ChunkBuffer.GetMeta(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; @@ -1515,7 +1515,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT MarkDirty(); - m_ChunkBuffer.SetBlock(a_RelX, a_RelY, a_RelZ, 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 ( @@ -1531,7 +1531,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta)); } - m_ChunkBuffer.SetMeta(a_RelX, a_RelY, a_RelZ, a_BlockMeta); + m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_BlockMeta); // ONLY recalculate lighting if it's necessary! if ( @@ -2438,7 +2438,7 @@ BLOCKTYPE cChunk::GetBlock(int a_RelX, int a_RelY, int a_RelZ) const return 0; // Clip } - return m_ChunkBuffer.GetBlock(a_RelX, a_RelY, a_RelZ); + return m_ChunkData.GetBlock(a_RelX, a_RelY, a_RelZ); } @@ -2448,7 +2448,7 @@ BLOCKTYPE cChunk::GetBlock(int a_RelX, int a_RelY, int a_RelZ) const void cChunk::GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) { a_BlockType = GetBlock(a_RelX, a_RelY, a_RelZ); - a_BlockMeta = m_ChunkBuffer.GetMeta(a_RelX, a_RelY, a_RelZ); + a_BlockMeta = m_ChunkData.GetMeta(a_RelX, a_RelY, a_RelZ); } @@ -2458,9 +2458,9 @@ 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) { a_BlockType = GetBlock(a_RelX, a_RelY, a_RelZ); - a_Meta = m_ChunkBuffer.GetMeta(a_RelX, a_RelY, a_RelZ); - a_SkyLight = m_ChunkBuffer.GetSkyLight(a_RelX, a_RelY, a_RelZ); - a_BlockLight = m_ChunkBuffer.GetBlockLight(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 038be42de..4f6c4cf0a 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -3,7 +3,7 @@ #include "Entities/Entity.h" #include "ChunkDef.h" -#include "ChunkBuffer.h" +#include "ChunkData.h" #include "Simulator/FireSimulator.h" #include "Simulator/SandSimulator.h" @@ -324,21 +324,21 @@ public: inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const { - return m_ChunkBuffer.GetMeta(a_RelX, a_RelY, a_RelZ); + 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) { if (!(GetMeta(a_RelX, a_RelY, a_RelZ) == a_Meta)) { MarkDirty(); - m_ChunkBuffer.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta); + m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta); 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 m_ChunkBuffer.GetBlockLight(a_RelX, a_RelY, a_RelZ); } - inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return m_ChunkBuffer.GetSkyLight(a_RelX, a_RelY, a_RelZ); } + 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; @@ -430,7 +430,7 @@ private: cWorld * m_World; cChunkMap * m_ChunkMap; - cChunkBuffer m_ChunkBuffer; + cChunkData m_ChunkData; cChunkDef::HeightMap m_HeightMap; cChunkDef::BiomeMap m_BiomeMap; diff --git a/src/ChunkBuffer.cpp b/src/ChunkData.cpp similarity index 88% rename from src/ChunkBuffer.cpp rename to src/ChunkData.cpp index 99bcdebef..160d118ad 100644 --- a/src/ChunkBuffer.cpp +++ b/src/ChunkData.cpp @@ -1,10 +1,10 @@ #include "Globals.h" -#include "ChunkBuffer.h" +#include "ChunkData.h" -cChunkBuffer cChunkBuffer::Copy() const +cChunkData cChunkData::Copy() const { - cChunkBuffer copy; + cChunkData copy; for (int i = 0; i < CHUNK_SECTION_NUM; i++) { if(m_Sections[i]) @@ -20,7 +20,7 @@ cChunkBuffer cChunkBuffer::Copy() const -void cChunkBuffer::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) const +void cChunkData::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) const { for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -54,7 +54,7 @@ void cChunkBuffer::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length -void cChunkBuffer::CopyMeta(NIBBLETYPE * a_dest) const +void cChunkData::CopyMeta(NIBBLETYPE * a_dest) const { for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -81,7 +81,7 @@ void cChunkBuffer::CopyMeta(NIBBLETYPE * a_dest) const -void cChunkBuffer::CopyLight(NIBBLETYPE * a_dest) const +void cChunkData::CopyLight(NIBBLETYPE * a_dest) const { for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -109,7 +109,7 @@ void cChunkBuffer::CopyLight(NIBBLETYPE * a_dest) const -void cChunkBuffer::CopySkyLight(NIBBLETYPE * a_dest) const +void cChunkData::CopySkyLight(NIBBLETYPE * a_dest) const { for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -137,7 +137,7 @@ void cChunkBuffer::CopySkyLight(NIBBLETYPE * a_dest) const -void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) +void cChunkData::SetBlocks(const BLOCKTYPE * a_src) { for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -175,7 +175,7 @@ void cChunkBuffer::SetBlocks(const BLOCKTYPE * a_src) -void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) +void cChunkData::SetMeta(const NIBBLETYPE * a_src) { for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -213,7 +213,7 @@ void cChunkBuffer::SetMeta(const NIBBLETYPE * a_src) -void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) +void cChunkData::SetLight(const NIBBLETYPE * a_src) { if (!a_src) return; for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) @@ -252,7 +252,7 @@ void cChunkBuffer::SetLight(const NIBBLETYPE * a_src) -void cChunkBuffer::SetSkyLight (const NIBBLETYPE * a_src) +void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) { if (!a_src) return; for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) @@ -292,22 +292,22 @@ void cChunkBuffer::SetSkyLight (const NIBBLETYPE * a_src) -cChunkBuffer::sChunkSection * cChunkBuffer::Allocate() const +cChunkData::sChunkSection * cChunkData::Allocate() const { // TODO: use a allocation pool - return new cChunkBuffer::sChunkSection; + return new cChunkData::sChunkSection; } -void cChunkBuffer::Free(cChunkBuffer::sChunkSection * ptr) const +void cChunkData::Free(cChunkData::sChunkSection * ptr) const { delete ptr; } -void cChunkBuffer::ZeroSection(cChunkBuffer::sChunkSection * ptr) const +void cChunkData::ZeroSection(cChunkData::sChunkSection * ptr) const { memset(ptr->m_BlockTypes,0x00,sizeof(ptr->m_BlockTypes)); memset(ptr->m_BlockMeta,0x00,sizeof(ptr->m_BlockMeta)); diff --git a/src/ChunkBuffer.h b/src/ChunkData.h similarity index 91% rename from src/ChunkBuffer.h rename to src/ChunkData.h index 266df2332..809f3cdf2 100644 --- a/src/ChunkBuffer.h +++ b/src/ChunkData.h @@ -17,11 +17,11 @@ // unique_ptr style interface for memory management #endif -class cChunkBuffer +class cChunkData { public: - cChunkBuffer() + cChunkData() #if __cplusplus < 201103L // auto_ptr style interface for memory management : IsOwner(true) @@ -29,7 +29,7 @@ public: { memset(m_Sections, 0, sizeof(m_Sections)); } - ~cChunkBuffer() + ~cChunkData() { #if __cplusplus < 201103L // auto_ptr style interface for memory management @@ -43,7 +43,7 @@ public: #if __cplusplus < 201103L // auto_ptr style interface for memory management - cChunkBuffer(const cChunkBuffer& other) : + cChunkData(const cChunkData& other) : IsOwner(true) { for (int i = 0; i < CHUNK_SECTION_NUM; i++) @@ -53,7 +53,7 @@ public: other.IsOwner = false; } - cChunkBuffer& operator=(const cChunkBuffer& other) + cChunkData& operator=(const cChunkData& other) { if(&other != this) { @@ -76,7 +76,7 @@ public: } #else // unique_ptr style interface for memory management - cChunkBuffer(cChunkBuffer&& other) + cChunkData(cChunkData&& other) { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -85,7 +85,7 @@ public: } } - cChunkBuffer& operator=(cChunkBuffer&& other) + cChunkData& operator=(cChunkData&& other) { if(&other != this) { @@ -125,7 +125,7 @@ public: (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0) ) { - ASSERT(!"cChunkBuffer::SetMeta(): index out of range!"); + ASSERT(!"cChunkData::SetMeta(): index out of range!"); return; } @@ -163,7 +163,7 @@ public: return 0; } } - ASSERT(!"cChunkBuffer::GetMeta(): coords out of chunk range!"); + ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); return 0; } @@ -175,7 +175,7 @@ public: (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0) ) { - ASSERT(!"cChunkBuffer::SetMeta(): index out of range!"); + ASSERT(!"cChunkData::SetMeta(): index out of range!"); return; } @@ -216,7 +216,7 @@ public: return 0; } } - ASSERT(!"cChunkBuffer::GetMeta(): coords out of chunk range!"); + ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); return 0; } @@ -235,11 +235,11 @@ public: return 0xF; } } - ASSERT(!"cChunkBuffer::GetMeta(): coords out of chunk range!"); + ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); return 0; } - cChunkBuffer Copy() const; + cChunkData Copy() const; void CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx = 0, size_t length = cChunkDef::NumBlocks) const; void CopyMeta (NIBBLETYPE * a_dest) const; void CopyLight (NIBBLETYPE * a_dest) const; diff --git a/src/ChunkDataCallback.h b/src/ChunkDataCallback.h index 76c45040e..340582885 100644 --- a/src/ChunkDataCallback.h +++ b/src/ChunkDataCallback.h @@ -3,7 +3,7 @@ #pragma once -#include "ChunkBuffer.h" +#include "ChunkData.h" /** Interface class used for getting data out of a chunk using the GetAllData() function. @@ -26,13 +26,13 @@ public: 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); }; + 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 ChunkBuffer (const cChunkBuffer & a_Buffer) {UNUSED(a_Buffer); }; + 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); }; @@ -43,16 +43,16 @@ public: /** A simple implementation of the cChunkDataCallback interface that collects all block data into a buffer */ -class cChunkBufferCollector : +class cChunkDataCollector : public cChunkDataCallback { public: - cChunkBuffer m_BlockData; + cChunkData m_BlockData; protected: - virtual void ChunkBuffer(const cChunkBuffer & a_BlockData) override + virtual void ChunkData(const cChunkData & a_BlockData) override { m_BlockData = a_BlockData.Copy(); } @@ -61,7 +61,7 @@ protected: /** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer */ -class cChunkDataCollector : +class cChunkDataArrayCollector : public cChunkDataCallback { public: @@ -71,7 +71,7 @@ public: protected: - virtual void ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override + virtual void ChunkData(const cChunkData & a_ChunkBuffer) override { a_ChunkBuffer.CopyBlocks(m_BlockData); a_ChunkBuffer.CopyMeta(m_BlockData + cChunkDef::NumBlocks); @@ -94,7 +94,7 @@ public: protected: - virtual void ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override + virtual void ChunkData(const cChunkData & a_ChunkBuffer) override { a_ChunkBuffer.CopyBlocks(m_BlockTypes); a_ChunkBuffer.CopyMeta(m_BlockMetas); diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index f961e35c6..879252c34 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -18,7 +18,7 @@ class cReader : public cChunkDataCallback { - virtual void ChunkBuffer(const cChunkBuffer & a_ChunkBuffer) override + virtual void ChunkData(const cChunkData & a_ChunkBuffer) override { BLOCKTYPE * OutputRows = m_BlockTypes; int InputIdx = 0; diff --git a/src/WorldStorage/WSSCompact.h b/src/WorldStorage/WSSCompact.h index 6c363d5ac..b148005f6 100644 --- a/src/WorldStorage/WSSCompact.h +++ b/src/WorldStorage/WSSCompact.h @@ -22,7 +22,7 @@ /// Helper class for serializing a chunk into Json class cJsonChunkSerializer : - public cChunkDataCollector + public cChunkDataArrayCollector { public: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1e3a01dc8..1fbd88f04 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,4 +4,4 @@ enable_testing() include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -add_subdirectory(ChunkBuffer) +add_subdirectory(ChunkData) diff --git a/tests/ChunkBuffer/ArraytoCoord.cpp b/tests/ChunkData/ArraytoCoord.cpp similarity index 97% rename from tests/ChunkBuffer/ArraytoCoord.cpp rename to tests/ChunkData/ArraytoCoord.cpp index 5563a3f86..fe82a3a7b 100644 --- a/tests/ChunkBuffer/ArraytoCoord.cpp +++ b/tests/ChunkData/ArraytoCoord.cpp @@ -1,6 +1,6 @@ #include "TestGlobals.h" -#include "ChunkBuffer.h" +#include "ChunkData.h" @@ -8,7 +8,7 @@ int main(int argc, char** argv) { { // Test first segment - cChunkBuffer buffer; + cChunkData buffer; BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); @@ -45,7 +45,7 @@ int main(int argc, char** argv) { // test following segment - cChunkBuffer buffer; + cChunkData buffer; BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); @@ -82,7 +82,7 @@ int main(int argc, char** argv) { // test zeros - cChunkBuffer buffer; + cChunkData buffer; BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); diff --git a/tests/ChunkBuffer/CMakeLists.txt b/tests/ChunkData/CMakeLists.txt similarity index 91% rename from tests/ChunkBuffer/CMakeLists.txt rename to tests/ChunkData/CMakeLists.txt index b216b1d39..3f6653bb5 100644 --- a/tests/ChunkBuffer/CMakeLists.txt +++ b/tests/ChunkData/CMakeLists.txt @@ -4,7 +4,7 @@ enable_testing() include_directories(${CMAKE_SOURCE_DIR}/src/) -add_library(ChunkBuffer ${CMAKE_SOURCE_DIR}/src/ChunkBuffer.cpp) +add_library(ChunkBuffer ${CMAKE_SOURCE_DIR}/src/ChunkData.cpp) add_executable(creatable-exe creatable.cpp) diff --git a/tests/ChunkBuffer/Coordinates.cpp b/tests/ChunkData/Coordinates.cpp similarity index 95% rename from tests/ChunkBuffer/Coordinates.cpp rename to tests/ChunkData/Coordinates.cpp index bed61d5dc..c0c46000e 100644 --- a/tests/ChunkBuffer/Coordinates.cpp +++ b/tests/ChunkData/Coordinates.cpp @@ -1,13 +1,13 @@ #include "TestGlobals.h" -#include "ChunkBuffer.h" +#include "ChunkData.h" int main(int argc, char** argv) { { - cChunkBuffer buffer; + cChunkData buffer; // Empty chunks buffer.SetBlock(0,0,0, 0xAB); @@ -105,7 +105,7 @@ int main(int argc, char** argv) } { - cChunkBuffer buffer; + cChunkData buffer; // Zero's buffer.SetBlock(0,0,0, 0x0); @@ -122,9 +122,9 @@ int main(int argc, char** argv) { // Operator = - cChunkBuffer buffer; + cChunkData buffer; buffer.SetBlock(0,0,0,0x42); - cChunkBuffer copy; + cChunkData copy; #if __cplusplus < 201103L copy = buffer; #else diff --git a/tests/ChunkBuffer/Copies.cpp b/tests/ChunkData/Copies.cpp similarity index 97% rename from tests/ChunkBuffer/Copies.cpp rename to tests/ChunkData/Copies.cpp index 76af81496..145ffd8e0 100644 --- a/tests/ChunkBuffer/Copies.cpp +++ b/tests/ChunkData/Copies.cpp @@ -1,18 +1,18 @@ #include "TestGlobals.h" -#include "ChunkBuffer.h" +#include "ChunkData.h" int main(int argc, char** argv) { { - cChunkBuffer buffer; + cChunkData buffer; buffer.SetBlock(3,1,4,0xDE); buffer.SetMeta(3,1,4,0xA); - cChunkBuffer copy = buffer.Copy(); + cChunkData copy = buffer.Copy(); testassert(copy.GetBlock(3,1,4) == 0xDE); testassert(copy.GetMeta(3,1,4) == 0xA); @@ -47,7 +47,7 @@ int main(int argc, char** argv) } { - cChunkBuffer buffer; + cChunkData buffer; NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) @@ -80,7 +80,7 @@ int main(int argc, char** argv) } { - cChunkBuffer buffer; + cChunkData buffer; NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) @@ -114,7 +114,7 @@ int main(int argc, char** argv) } { - cChunkBuffer buffer; + cChunkData buffer; NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) @@ -148,7 +148,7 @@ int main(int argc, char** argv) } { - cChunkBuffer buffer; + cChunkData buffer; BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); diff --git a/tests/ChunkBuffer/creatable.cpp b/tests/ChunkData/creatable.cpp similarity index 61% rename from tests/ChunkBuffer/creatable.cpp rename to tests/ChunkData/creatable.cpp index 49204c879..74025cb14 100644 --- a/tests/ChunkBuffer/creatable.cpp +++ b/tests/ChunkData/creatable.cpp @@ -1,9 +1,9 @@ #include "TestGlobals.h" -#include "ChunkBuffer.h" +#include "ChunkData.h" int main(int argc, char** argv) { - cChunkBuffer buffer; + cChunkData buffer; return 0; } From 5929ffbc40d24f4e69cf12c8495d194407547c9c Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 21 May 2014 20:08:34 +0100 Subject: [PATCH 088/312] Fixed stylistic issues --- src/BlockArea.cpp | 8 ++++---- src/Chunk.cpp | 4 ++-- src/ChunkData.cpp | 18 +++++++++--------- src/ChunkData.h | 20 ++++++++++---------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 0c46e59e5..abbfca767 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -1838,7 +1838,7 @@ bool cBlockArea::cChunkReader::Coords(int a_ChunkX, int a_ChunkZ) void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) { { - if (!(m_Area.m_BlockTypes == NULL)) + if (m_Area.m_BlockTypes != NULL) { int SizeY = m_Area.m_Size.y; int MinY = m_Origin.y; @@ -1901,17 +1901,17 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) } } - if (m_Area.m_BlockMetas) + if (m_Area.m_BlockMetas != NULL) { a_BlockBuffer.CopyMeta(m_Area.m_BlockMetas); } - if (m_Area.m_BlockLight) + if (m_Area.m_BlockLight != NULL) { a_BlockBuffer.CopyLight(m_Area.m_BlockLight); } - if (m_Area.m_BlockSkyLight) + if (m_Area.m_BlockSkyLight != NULL) { a_BlockBuffer.CopySkyLight(m_Area.m_BlockSkyLight); } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index a45ed32c1..d85b44607 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -326,9 +326,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 :) - m_ChunkData.SetLight (a_BlockLight); + m_ChunkData.SetLight(a_BlockLight); - m_ChunkData.SetSkyLight (a_SkyLight); + m_ChunkData.SetSkyLight(a_SkyLight); m_IsLightValid = true; } diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 160d118ad..7194eca92 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -7,7 +7,7 @@ cChunkData cChunkData::Copy() const cChunkData copy; for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i]) + if(m_Sections[i] == NULL) { copy.m_Sections[i] = Allocate(); *copy.m_Sections[i] = *m_Sections[i]; @@ -30,7 +30,7 @@ void cChunkData::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) { size_t tocopy = length > segment_length ? segment_length : length; length -= tocopy; - if(m_Sections[i]) + if(m_Sections[i] == NULL) { memcpy( &a_dest[i * segment_length], @@ -59,7 +59,7 @@ void cChunkData::CopyMeta(NIBBLETYPE * a_dest) const for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if(m_Sections[i]) + if(m_Sections[i] == NULL) { memcpy( &a_dest[i * segment_length], @@ -86,7 +86,7 @@ void cChunkData::CopyLight(NIBBLETYPE * a_dest) const for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if(m_Sections[i]) + if(m_Sections[i] == NULL) { memcpy( &a_dest[i * segment_length], @@ -114,7 +114,7 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_dest) const for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if(m_Sections[i]) + if(m_Sections[i] == NULL) { memcpy( &a_dest[i * segment_length], @@ -142,7 +142,7 @@ void cChunkData::SetBlocks(const BLOCKTYPE * a_src) for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; - if (m_Sections[i]) + if (m_Sections[i] == NULL) { memcpy(&m_Sections[i]->m_BlockTypes, &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length); } @@ -180,7 +180,7 @@ void cChunkData::SetMeta(const NIBBLETYPE * a_src) for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if (m_Sections[i]) + if (m_Sections[i] == NULL) { memcpy(&m_Sections[i]->m_BlockMeta, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); } @@ -219,7 +219,7 @@ void cChunkData::SetLight(const NIBBLETYPE * a_src) for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if (m_Sections[i]) + if (m_Sections[i] == NULL) { memcpy(&m_Sections[i]->m_BlockLight, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); } @@ -258,7 +258,7 @@ void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if (m_Sections[i]) + if (m_Sections[i] == NULL) { memcpy(&m_Sections[i]->m_BlockSkyLight, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); } diff --git a/src/ChunkData.h b/src/ChunkData.h index 809f3cdf2..24a437629 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -37,7 +37,7 @@ public: #endif for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i]) Free(m_Sections[i]);; + if(m_Sections[i] == NULL) Free(m_Sections[i]);; } } @@ -91,7 +91,7 @@ public: { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i]) Free(m_Sections[i]);; + Free(m_Sections[i]);; m_Sections[i] = other.m_Sections[i]; other.m_Sections[i] = 0; } @@ -106,7 +106,7 @@ public: ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height)); ASSERT((a_Z >= 0) && (a_Z < cChunkDef::Width)); int Section = a_Y / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section]) + if(m_Sections[Section] == NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * CHUNK_SECTION_HEIGHT), a_Z); return m_Sections[Section]->m_BlockTypes[Index]; @@ -130,14 +130,14 @@ public: } int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if(!m_Sections[Section]) + if(m_Sections[Section] != NULL) { if(a_Block == 0x00) { return; } m_Sections[Section] = Allocate(); - if(!m_Sections[Section]) + if(m_Sections[Section] != NULL) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return; @@ -153,7 +153,7 @@ public: 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 / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section]) + if(m_Sections[Section] == NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); return (m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4)) & 0x0f; @@ -180,14 +180,14 @@ public: } int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if(!m_Sections[Section]) + if(m_Sections[Section] != NULL) { if((a_Nibble & 0xf) == 0x00) { return; } m_Sections[Section] = Allocate(); - if(!m_Sections[Section]) + if(m_Sections[Section] != NULL) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return; @@ -206,7 +206,7 @@ public: 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 / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section]) + if(m_Sections[Section] == NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; @@ -225,7 +225,7 @@ public: 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 / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section]) + if(m_Sections[Section] == NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; From bd880603a560160d247d79a2fdeb3fbab26994f0 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 21 May 2014 20:18:09 +0100 Subject: [PATCH 089/312] Changed cChunkData::SetMeta to return a bool indicating whether the value changed --- src/Chunk.h | 6 +++--- src/ChunkData.h | 10 ++++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Chunk.h b/src/Chunk.h index 4f6c4cf0a..2de45919e 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -328,11 +328,11 @@ public: } inline void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Meta) { - if (!(GetMeta(a_RelX, a_RelY, a_RelZ) == a_Meta)) + bool hasChanged = m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta); + if (hasChanged) { MarkDirty(); - m_ChunkData.SetMeta(a_RelX, a_RelY, a_RelZ, a_Meta); - + m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, GetBlock(a_RelX, a_RelY, a_RelZ), a_Meta)); } } diff --git a/src/ChunkData.h b/src/ChunkData.h index 24a437629..73b1e8c6a 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -167,7 +167,7 @@ public: return 0; } - void SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble) + bool SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble) { if ( (a_RelX >= cChunkDef::Width) || (a_RelX < 0) || @@ -176,7 +176,7 @@ public: ) { ASSERT(!"cChunkData::SetMeta(): index out of range!"); - return; + return false; } int Section = a_RelY / CHUNK_SECTION_HEIGHT; @@ -184,21 +184,23 @@ public: { if((a_Nibble & 0xf) == 0x00) { - return; + return false; } m_Sections[Section] = Allocate(); if(m_Sections[Section] != NULL) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); - return; + return false; } ZeroSection(m_Sections[Section]); } int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + NIBBLETYPE oldval = m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4) & 0xf; m_Sections[Section]->m_BlockMeta[Index / 2] = static_cast( (m_Sections[Section]->m_BlockMeta[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set ); + return oldval == a_Nibble; } NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const From 93c0dcb1feb6daebbea586e750b586ec6588bfa2 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 21 May 2014 20:26:43 +0100 Subject: [PATCH 090/312] Added space to ChunkData.cpp --- src/ChunkData.cpp | 120 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 100 insertions(+), 20 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 7194eca92..f8c4a851d 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -144,7 +144,11 @@ void cChunkData::SetBlocks(const BLOCKTYPE * a_src) const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; if (m_Sections[i] == NULL) { - memcpy(&m_Sections[i]->m_BlockTypes, &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length); + memcpy( + &m_Sections[i]->m_BlockTypes, + &a_src[i * segment_length], + sizeof(BLOCKTYPE) * segment_length + ); } else { @@ -159,9 +163,21 @@ void cChunkData::SetBlocks(const BLOCKTYPE * a_src) &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); - memset(m_Sections[i]->m_BlockMeta,0x00,sizeof(m_Sections[i]->m_BlockMeta)); - 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)); + memset( + m_Sections[i]->m_BlockMeta, + 0x00, + sizeof(m_Sections[i]->m_BlockMeta) + ); + 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) + ); } else { @@ -182,7 +198,11 @@ void cChunkData::SetMeta(const NIBBLETYPE * a_src) const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] == NULL) { - memcpy(&m_Sections[i]->m_BlockMeta, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); + memcpy( + &m_Sections[i]->m_BlockMeta, + &a_src[i * segment_length], + sizeof(NIBBLETYPE) * segment_length + ); } else { @@ -197,9 +217,21 @@ void cChunkData::SetMeta(const NIBBLETYPE * a_src) &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); - 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)); + 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) + ); } else { @@ -221,7 +253,11 @@ void cChunkData::SetLight(const NIBBLETYPE * a_src) const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] == NULL) { - memcpy(&m_Sections[i]->m_BlockLight, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); + memcpy( + &m_Sections[i]->m_BlockLight, + &a_src[i * segment_length], + sizeof(NIBBLETYPE) * segment_length + ); } else { @@ -236,9 +272,21 @@ void cChunkData::SetLight(const NIBBLETYPE * a_src) &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); - memset(m_Sections[i]->m_BlockTypes,0x00,sizeof(m_Sections[i]->m_BlockTypes)); - memset(m_Sections[i]->m_BlockMeta,0x00,sizeof(m_Sections[i]->m_BlockMeta)); - memset(m_Sections[i]->m_BlockSkyLight,0xFF,sizeof(m_Sections[i]->m_BlockSkyLight)); + memset( + m_Sections[i]->m_BlockTypes, + 0x00, + sizeof(m_Sections[i]->m_BlockTypes) + ); + memset( + m_Sections[i]->m_BlockMeta, + 0x00, + sizeof(m_Sections[i]->m_BlockMeta) + ); + memset( + m_Sections[i]->m_BlockSkyLight, + 0xFF, + sizeof(m_Sections[i]->m_BlockSkyLight) + ); } else { @@ -260,7 +308,11 @@ void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] == NULL) { - memcpy(&m_Sections[i]->m_BlockSkyLight, &a_src[i * segment_length], sizeof(NIBBLETYPE) * segment_length); + memcpy( + &m_Sections[i]->m_BlockSkyLight, + &a_src[i * segment_length], + sizeof(NIBBLETYPE) * segment_length + ); } else { @@ -275,9 +327,21 @@ void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) &a_src[i * segment_length], sizeof(BLOCKTYPE) * segment_length ); - memset(m_Sections[i]->m_BlockTypes,0x00,sizeof(m_Sections[i]->m_BlockTypes)); - memset(m_Sections[i]->m_BlockMeta,0x00,sizeof(m_Sections[i]->m_BlockMeta)); - memset(m_Sections[i]->m_BlockLight,0x00,sizeof(m_Sections[i]->m_BlockLight)); + memset( + m_Sections[i]->m_BlockTypes, + 0x00, + sizeof(m_Sections[i]->m_BlockTypes) + ); + memset( + m_Sections[i]->m_BlockMeta, + 0x00, + sizeof(m_Sections[i]->m_BlockMeta) + ); + memset( + m_Sections[i]->m_BlockLight, + 0x00, + sizeof(m_Sections[i]->m_BlockLight) + ); } else { @@ -309,10 +373,26 @@ void cChunkData::Free(cChunkData::sChunkSection * ptr) const void cChunkData::ZeroSection(cChunkData::sChunkSection * ptr) const { - memset(ptr->m_BlockTypes,0x00,sizeof(ptr->m_BlockTypes)); - memset(ptr->m_BlockMeta,0x00,sizeof(ptr->m_BlockMeta)); - memset(ptr->m_BlockLight,0x00,sizeof(ptr->m_BlockLight)); - memset(ptr->m_BlockSkyLight,0xFF,sizeof(ptr->m_BlockSkyLight)); + memset( + ptr->m_BlockTypes, + 0x00, + sizeof(ptr->m_BlockTypes) + ); + memset( + ptr->m_BlockMeta, + 0x00, + sizeof(ptr->m_BlockMeta) + ); + memset( + ptr->m_BlockLight, + 0x00, + sizeof(ptr->m_BlockLight) + ); + memset( + ptr->m_BlockSkyLight, + 0xFF, + sizeof(ptr->m_BlockSkyLight) + ); } From 88c61a2e96af9c7d1b173c0b580cef2c348850d7 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 21 May 2014 21:18:14 +0100 Subject: [PATCH 091/312] Fixed reversed comparisons to null --- src/ChunkData.cpp | 18 +++++++++--------- src/ChunkData.h | 16 ++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index f8c4a851d..0cacaf02d 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -7,7 +7,7 @@ cChunkData cChunkData::Copy() const cChunkData copy; for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i] == NULL) + if(m_Sections[i] != NULL) { copy.m_Sections[i] = Allocate(); *copy.m_Sections[i] = *m_Sections[i]; @@ -30,7 +30,7 @@ void cChunkData::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) { size_t tocopy = length > segment_length ? segment_length : length; length -= tocopy; - if(m_Sections[i] == NULL) + if(m_Sections[i] != NULL) { memcpy( &a_dest[i * segment_length], @@ -59,7 +59,7 @@ void cChunkData::CopyMeta(NIBBLETYPE * a_dest) const for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if(m_Sections[i] == NULL) + if(m_Sections[i] != NULL) { memcpy( &a_dest[i * segment_length], @@ -86,7 +86,7 @@ void cChunkData::CopyLight(NIBBLETYPE * a_dest) const for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if(m_Sections[i] == NULL) + if(m_Sections[i] != NULL) { memcpy( &a_dest[i * segment_length], @@ -114,7 +114,7 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_dest) const for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if(m_Sections[i] == NULL) + if(m_Sections[i] != NULL) { memcpy( &a_dest[i * segment_length], @@ -142,7 +142,7 @@ void cChunkData::SetBlocks(const BLOCKTYPE * a_src) for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; - if (m_Sections[i] == NULL) + if (m_Sections[i] != NULL) { memcpy( &m_Sections[i]->m_BlockTypes, @@ -196,7 +196,7 @@ void cChunkData::SetMeta(const NIBBLETYPE * a_src) for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if (m_Sections[i] == NULL) + if (m_Sections[i] != NULL) { memcpy( &m_Sections[i]->m_BlockMeta, @@ -251,7 +251,7 @@ void cChunkData::SetLight(const NIBBLETYPE * a_src) for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if (m_Sections[i] == NULL) + if (m_Sections[i] != NULL) { memcpy( &m_Sections[i]->m_BlockLight, @@ -306,7 +306,7 @@ void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if (m_Sections[i] == NULL) + if (m_Sections[i] != NULL) { memcpy( &m_Sections[i]->m_BlockSkyLight, diff --git a/src/ChunkData.h b/src/ChunkData.h index 73b1e8c6a..51244225b 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -106,7 +106,7 @@ public: ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height)); ASSERT((a_Z >= 0) && (a_Z < cChunkDef::Width)); int Section = a_Y / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] == NULL) + if(m_Sections[Section] != NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * CHUNK_SECTION_HEIGHT), a_Z); return m_Sections[Section]->m_BlockTypes[Index]; @@ -130,14 +130,14 @@ public: } int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] != NULL) + if(m_Sections[Section] == NULL) { if(a_Block == 0x00) { return; } m_Sections[Section] = Allocate(); - if(m_Sections[Section] != NULL) + if(m_Sections[Section] == NULL) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return; @@ -153,7 +153,7 @@ public: 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 / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] == NULL) + if(m_Sections[Section] != NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); return (m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4)) & 0x0f; @@ -180,14 +180,14 @@ public: } int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] != NULL) + if(m_Sections[Section] == NULL) { if((a_Nibble & 0xf) == 0x00) { return false; } m_Sections[Section] = Allocate(); - if(m_Sections[Section] != NULL) + if(m_Sections[Section] == NULL) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return false; @@ -208,7 +208,7 @@ public: 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 / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] == NULL) + if(m_Sections[Section] != NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; @@ -227,7 +227,7 @@ public: 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 / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] == NULL) + if(m_Sections[Section] != NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; From 4b23472097fa2daee464b6c5d73da56a0706731c Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 21 May 2014 21:46:20 +0100 Subject: [PATCH 092/312] Fixed if spaces --- src/ChunkData.cpp | 13 +++++++------ src/ChunkData.h | 32 ++++++++++++++++---------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 0cacaf02d..86b0c431c 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -7,7 +7,7 @@ cChunkData cChunkData::Copy() const cChunkData copy; for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i] != NULL) + if (m_Sections[i] != NULL) { copy.m_Sections[i] = Allocate(); *copy.m_Sections[i] = *m_Sections[i]; @@ -30,7 +30,7 @@ void cChunkData::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) { size_t tocopy = length > segment_length ? segment_length : length; length -= tocopy; - if(m_Sections[i] != NULL) + if (m_Sections[i] != NULL) { memcpy( &a_dest[i * segment_length], @@ -59,12 +59,13 @@ void cChunkData::CopyMeta(NIBBLETYPE * a_dest) const for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if(m_Sections[i] != NULL) + if (m_Sections[i] != NULL) { memcpy( &a_dest[i * segment_length], &m_Sections[i]->m_BlockMeta, - sizeof(NIBBLETYPE) * segment_length); + sizeof(NIBBLETYPE) * segment_length + ); } else { @@ -86,7 +87,7 @@ void cChunkData::CopyLight(NIBBLETYPE * a_dest) const for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if(m_Sections[i] != NULL) + if (m_Sections[i] != NULL) { memcpy( &a_dest[i * segment_length], @@ -114,7 +115,7 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_dest) const for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; - if(m_Sections[i] != NULL) + if (m_Sections[i] != NULL) { memcpy( &a_dest[i * segment_length], diff --git a/src/ChunkData.h b/src/ChunkData.h index 51244225b..9c852ee24 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -33,11 +33,11 @@ public: { #if __cplusplus < 201103L // auto_ptr style interface for memory management - if(!IsOwner) return; + if (!IsOwner) return; #endif for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i] == NULL) Free(m_Sections[i]);; + if (m_Sections[i] == NULL) Free(m_Sections[i]);; } } @@ -55,13 +55,13 @@ public: cChunkData& operator=(const cChunkData& other) { - if(&other != this) + if (&other != this) { - if(IsOwner) + if (IsOwner) { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { - if(m_Sections[i]) Free(m_Sections[i]);; + if (m_Sections[i]) Free(m_Sections[i]);; } } IsOwner = true; @@ -87,7 +87,7 @@ public: cChunkData& operator=(cChunkData&& other) { - if(&other != this) + if (&other != this) { for (int i = 0; i < CHUNK_SECTION_NUM; i++) { @@ -106,7 +106,7 @@ public: ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height)); ASSERT((a_Z >= 0) && (a_Z < cChunkDef::Width)); int Section = a_Y / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] != NULL) + if (m_Sections[Section] != NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * CHUNK_SECTION_HEIGHT), a_Z); return m_Sections[Section]->m_BlockTypes[Index]; @@ -130,14 +130,14 @@ public: } int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] == NULL) + if (m_Sections[Section] == NULL) { - if(a_Block == 0x00) + if (a_Block == 0x00) { return; } m_Sections[Section] = Allocate(); - if(m_Sections[Section] == NULL) + if (m_Sections[Section] == NULL) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return; @@ -153,7 +153,7 @@ public: 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 / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] != NULL) + if (m_Sections[Section] != NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); return (m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4)) & 0x0f; @@ -180,14 +180,14 @@ public: } int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] == NULL) + if (m_Sections[Section] == NULL) { - if((a_Nibble & 0xf) == 0x00) + if ((a_Nibble & 0xf) == 0x00) { return false; } m_Sections[Section] = Allocate(); - if(m_Sections[Section] == NULL) + if (m_Sections[Section] == NULL) { ASSERT(!"Failed to allocate a new section in Chunkbuffer"); return false; @@ -208,7 +208,7 @@ public: 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 / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] != NULL) + if (m_Sections[Section] != NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; @@ -227,7 +227,7 @@ public: 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 / CHUNK_SECTION_HEIGHT; - if(m_Sections[Section] != NULL) + if (m_Sections[Section] != NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; From efcae77828d52680f9521793520ffc4325b465b8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 21 May 2014 23:16:43 +0200 Subject: [PATCH 093/312] Added second kind of desert village (FlatRoof). --- .../Prefabs/SandFlatRoofVillagePrefabs.cpp | 1511 +++++++++++++++++ .../Prefabs/SandFlatRoofVillagePrefabs.h | 15 + src/Generating/VillageGen.cpp | 13 +- 3 files changed, 1535 insertions(+), 4 deletions(-) create mode 100644 src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp create mode 100644 src/Generating/Prefabs/SandFlatRoofVillagePrefabs.h diff --git a/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp new file mode 100644 index 000000000..93aa405c2 --- /dev/null +++ b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp @@ -0,0 +1,1511 @@ + +// 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, 5, 10, // SizeX = 12, SizeY = 5, SizeZ = 10 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 11, 4, 9, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a:128: 2\n" /* sandstonestairs */ + "b:128: 1\n" /* sandstonestairs */ + "c:128: 0\n" /* sandstonestairs */ + "d: 24: 0\n" /* sandstone */ + "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 */ "aaaaaab....." + /* 1 */ "cdddddddddd." + /* 2 */ "cdddddddddd." + /* 3 */ "cdddddddddd." + /* 4 */ "cdddddddddd." + /* 5 */ "edddddddddd." + /* 6 */ ".dddddddddd." + /* 7 */ ".dddddddddd." + /* 8 */ ".dddddddddd." + /* 9 */ "............" + + // Level 1 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".d....ddddd." + /* 2 */ "......dfffd." + /* 3 */ "......ghfhd." + /* 4 */ "......diiid." + /* 5 */ ".d....dhfhd." + /* 6 */ ".djddjdfffd." + /* 7 */ ".ddkkddl..d." + /* 8 */ ".dddddddddd." + /* 9 */ "............" + + // Level 2 + /* 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 3 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "............" + /* 1 */ ".d....ddddd." + /* 2 */ "......d...d." + /* 3 */ "......d...d." + /* 4 */ "......dp..d." + /* 5 */ ".d....d...d." + /* 6 */ ".dqqqqd...d." + /* 7 */ ".d....d...d." + /* 8 */ ".dddddddddd." + /* 9 */ "............" + + // Level 4 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "rsssssssssss" + /* 1 */ "rddddddddddt" + /* 2 */ "rddddddddddt" + /* 3 */ "rddddddddddt" + /* 4 */ "rddddddddddt" + /* 5 */ "rddddddddddt" + /* 6 */ "rddddddddddt" + /* 7 */ "rddddddddddt" + /* 8 */ "rddddddddddt" + /* 9 */ "uuuuuuuuuuut", + + // Connectors: + "-1: 3, 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, + }, // Forge + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // House11x7: + // The data has been exported from the gallery Desert, area index 31, ID 172, created by Aloe_vera + { + // Size: + 13, 5, 9, // SizeX = 13, SizeY = 5, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 12, 4, 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: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 */ "..abc........" + /* 1 */ ".ddddddddddd." + /* 2 */ ".ddddddddddd." + /* 3 */ ".ddddddddddd." + /* 4 */ ".ddddddddddd." + /* 5 */ ".ddddddddddd." + /* 6 */ ".ddddddddddd." + /* 7 */ ".ddddddddddd." + /* 8 */ "............." + + // Level 1 + /* z\x* 111 */ + /* * 0123456789012 */ + /* 0 */ "............." + /* 1 */ ".ddedddddddd." + /* 2 */ ".dffgggggffd." + /* 3 */ ".dfghhhhhgfd." + /* 4 */ ".dfghfffhgfd." + /* 5 */ ".dfghhhhhgfd." + /* 6 */ ".dffgggggffd." + /* 7 */ ".ddddddddddd." + /* 8 */ "............." + + // Level 2 + /* 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 3 + /* z\x* 111 */ + /* * 0123456789012 */ + /* 0 */ "............." + /* 1 */ ".ddddddddddd." + /* 2 */ ".d..k..k...d." + /* 3 */ ".d.........d." + /* 4 */ ".dl.......nd." + /* 5 */ ".d.........d." + /* 6 */ ".d....o....d." + /* 7 */ ".ddddddddddd." + /* 8 */ "............." + + // Level 4 + /* z\x* 111 */ + /* * 0123456789012 */ + /* 0 */ "pqqqqqqqqqqqq" + /* 1 */ "pdddddddddddr" + /* 2 */ "pdddddddddddr" + /* 3 */ "pdddddddddddr" + /* 4 */ "pdddddddddddr" + /* 5 */ "pdddddddddddr" + /* 6 */ "pdddddddddddr" + /* 7 */ "pdddddddddddr" + /* 8 */ "ssssssssssssr", + + // Connectors: + "-1: 3, 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, + }, // House11x7 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // House5x4: + // The data has been exported from the gallery Desert, area index 25, ID 166, created by Aloe_vera + { + // Size: + 7, 5, 6, // SizeX = 7, SizeY = 5, SizeZ = 6 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 4, 5, // 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: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 */ "..abc.." + /* 1 */ ".ddddd." + /* 2 */ ".ddddd." + /* 3 */ ".ddddd." + /* 4 */ ".ddddd." + /* 5 */ "......." + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ddedd." + /* 2 */ ".dfgfd." + /* 3 */ ".dfgfd." + /* 4 */ ".ddddd." + /* 5 */ "......." + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".hhihh." + /* 2 */ ".h...h." + /* 3 */ ".h...h." + /* 4 */ ".hh.hh." + /* 5 */ "......." + + // Level 3 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ddddd." + /* 2 */ ".dj.jd." + /* 3 */ ".d...d." + /* 4 */ ".ddddd." + /* 5 */ "......." + + // Level 4 + /* z\x* 0123456 */ + /* 0 */ "kllllln" + /* 1 */ "kdddddn" + /* 2 */ "kdddddn" + /* 3 */ "kdddddn" + /* 4 */ "kdddddn" + /* 5 */ "oooooon", + + // Connectors: + "-1: 3, 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, + }, // House5x4 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // House5x5: + // The data has been exported from the gallery Desert, area index 26, ID 167, created by Aloe_vera + { + // Size: + 7, 5, 7, // SizeX = 7, SizeY = 5, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 4, 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: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 */ "..abc.." + /* 1 */ ".ddddd." + /* 2 */ ".ddddd." + /* 3 */ ".ddddd." + /* 4 */ ".ddddd." + /* 5 */ ".ddddd." + /* 6 */ "......." + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ddedd." + /* 2 */ ".dfffd." + /* 3 */ ".dghgd." + /* 4 */ ".dfffd." + /* 5 */ ".ddddd." + /* 6 */ "......." + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".iijii." + /* 2 */ ".i...i." + /* 3 */ "......." + /* 4 */ ".i...i." + /* 5 */ ".ii.ii." + /* 6 */ "......." + + // Level 3 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ ".ddddd." + /* 2 */ ".dk.kd." + /* 3 */ ".d...d." + /* 4 */ ".d...d." + /* 5 */ ".ddddd." + /* 6 */ "......." + + // Level 4 + /* z\x* 0123456 */ + /* 0 */ "lnnnnno" + /* 1 */ "ldddddo" + /* 2 */ "ldddddo" + /* 3 */ "ldddddo" + /* 4 */ "ldddddo" + /* 5 */ "ldddddo" + /* 6 */ "ppppppo", + + // Connectors: + "-1: 3, 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, + }, // House5x5 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // House7x5: + // The data has been exported from the gallery Desert, area index 27, ID 168, created by Aloe_vera + { + // Size: + 9, 5, 7, // SizeX = 9, SizeY = 5, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 8, 4, 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: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 */ "..abc...." + /* 1 */ ".ddddddd." + /* 2 */ ".ddddddd." + /* 3 */ ".ddddddd." + /* 4 */ ".ddddddd." + /* 5 */ ".ddddddd." + /* 6 */ "........." + + // Level 1 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ ".ddedddd." + /* 2 */ ".dfffffd." + /* 3 */ ".dghhhgd." + /* 4 */ ".dfffffd." + /* 5 */ ".ddddddd." + /* 6 */ "........." + + // Level 2 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ ".iiji.ii." + /* 2 */ ".i.....i." + /* 3 */ "........." + /* 4 */ ".i.....i." + /* 5 */ ".iii.iii." + /* 6 */ "........." + + // Level 3 + /* z\x* 012345678 */ + /* 0 */ "........." + /* 1 */ ".ddddddd." + /* 2 */ ".dk.k..d." + /* 3 */ ".d.....d." + /* 4 */ ".d.....d." + /* 5 */ ".ddddddd." + /* 6 */ "........." + + // Level 4 + /* z\x* 012345678 */ + /* 0 */ "lnnnnnnnn" + /* 1 */ "ldddddddo" + /* 2 */ "ldddddddo" + /* 3 */ "ldddddddo" + /* 4 */ "ldddddddo" + /* 5 */ "ldddddddo" + /* 6 */ "ppppppppo", + + // Connectors: + "-1: 3, 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, + }, // House7x5 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // House8x5: + // The data has been exported from the gallery Desert, area index 28, ID 169, created by Aloe_vera + { + // Size: + 10, 5, 7, // SizeX = 10, SizeY = 5, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 9, 4, 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: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 */ "..abc....." + /* 1 */ ".dddddddd." + /* 2 */ ".dddddddd." + /* 3 */ ".dddddddd." + /* 4 */ ".dddddddd." + /* 5 */ ".dddddddd." + /* 6 */ ".........." + + // Level 1 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ ".........." + /* 1 */ ".ddeddddd." + /* 2 */ ".dfghhgfd." + /* 3 */ ".dfhffhfd." + /* 4 */ ".dfghhgfd." + /* 5 */ ".dddddddd." + /* 6 */ ".........." + + // Level 2 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ ".........." + /* 1 */ ".iijii.ii." + /* 2 */ ".i......i." + /* 3 */ ".........." + /* 4 */ ".i......i." + /* 5 */ ".ii.ii.ii." + /* 6 */ ".........." + + // Level 3 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ ".........." + /* 1 */ ".dddddddd." + /* 2 */ ".dk.k...d." + /* 3 */ ".d......d." + /* 4 */ ".d......d." + /* 5 */ ".dddddddd." + /* 6 */ ".........." + + // Level 4 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "lnnnnnnnnn" + /* 1 */ "lddddddddo" + /* 2 */ "lddddddddo" + /* 3 */ "lddddddddo" + /* 4 */ "lddddddddo" + /* 5 */ "lddddddddo" + /* 6 */ "pppppppppo", + + // Connectors: + "-1: 3, 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, + }, // House8x5 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // House8x7: + // The data has been exported from the gallery Desert, area index 29, ID 170, created by Aloe_vera + { + // Size: + 10, 5, 9, // SizeX = 10, SizeY = 5, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 9, 4, 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: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 */ "..abc....." + /* 1 */ ".dddddddd." + /* 2 */ ".dddddddd." + /* 3 */ ".dddddddd." + /* 4 */ ".dddddddd." + /* 5 */ ".dddddddd." + /* 6 */ ".dddddddd." + /* 7 */ ".dddddddd." + /* 8 */ ".........." + + // Level 1 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ ".........." + /* 1 */ ".ddeddddd." + /* 2 */ ".dfghhgfd." + /* 3 */ ".dfhffhfd." + /* 4 */ ".dfhgghfd." + /* 5 */ ".dfhffhfd." + /* 6 */ ".dfghhgfd." + /* 7 */ ".dddddddd." + /* 8 */ ".........." + + // Level 2 + /* 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 3 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ ".........." + /* 1 */ ".dddddddd." + /* 2 */ ".d..k...d." + /* 3 */ ".d......d." + /* 4 */ ".dl....nd." + /* 5 */ ".d......d." + /* 6 */ ".d......d." + /* 7 */ ".dddddddd." + /* 8 */ ".........." + + // Level 4 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "oppppppppp" + /* 1 */ "oddddddddq" + /* 2 */ "oddddddddq" + /* 3 */ "oddddddddq" + /* 4 */ "oddddddddq" + /* 5 */ "oddddddddq" + /* 6 */ "oddddddddq" + /* 7 */ "oddddddddq" + /* 8 */ "rrrrrrrrrq", + + // Connectors: + "-1: 3, 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, + }, // House8x7 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // House9x7: + // The data has been exported from the gallery Desert, area index 30, ID 171, created by Aloe_vera + { + // Size: + 11, 5, 9, // SizeX = 11, SizeY = 5, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 4, 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: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 */ "..abc......" + /* 1 */ ".ddddddddd." + /* 2 */ ".ddddddddd." + /* 3 */ ".ddddddddd." + /* 4 */ ".ddddddddd." + /* 5 */ ".ddddddddd." + /* 6 */ ".ddddddddd." + /* 7 */ ".ddddddddd." + /* 8 */ "..........." + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".ddedddddd." + /* 2 */ ".dffgggffd." + /* 3 */ ".dfghhhgfd." + /* 4 */ ".dfghfhgfd." + /* 5 */ ".dfghhhgfd." + /* 6 */ ".dffgggffd." + /* 7 */ ".ddddddddd." + /* 8 */ "..........." + + // Level 2 + /* 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 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ ".ddddddddd." + /* 2 */ ".d..k....d." + /* 3 */ ".d.......d." + /* 4 */ ".dl.....nd." + /* 5 */ ".d.......d." + /* 6 */ ".d...o...d." + /* 7 */ ".ddddddddd." + /* 8 */ "..........." + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "pqqqqqqqqqq" + /* 1 */ "pdddddddddr" + /* 2 */ "pdddddddddr" + /* 3 */ "pdddddddddr" + /* 4 */ "pdddddddddr" + /* 5 */ "pdddddddddr" + /* 6 */ "pdddddddddr" + /* 7 */ "pdddddddddr" + /* 8 */ "ssssssssssr", + + // Connectors: + "-1: 3, 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, + }, // 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, + }, // HouseL13x12 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // MarketStall: + // The data has been exported from the gallery Desert, area index 34, ID 175, created by Aloe_vera + { + // Size: + 7, 5, 7, // SizeX = 7, SizeY = 5, SizeZ = 7 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 6, 4, 6, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 85: 0\n" /* fence */ + "b:171:14\n" /* carpet */ + "c:171:15\n" /* carpet */ + "d:171: 0\n" /* carpet */ + "e: 35:14\n" /* wool */ + "f: 35: 0\n" /* wool */ + "m: 19: 0\n" /* sponge */, + + // Block data: + // Level 0 + /* z\x* 0123456 */ + /* 0 */ "a.....a" + /* 1 */ "bccdccb" + /* 2 */ "bcdddcb" + /* 3 */ "bcdddcb" + /* 4 */ "bccdccb" + /* 5 */ "a.....a" + /* 6 */ "......." + + // Level 1 + /* z\x* 0123456 */ + /* 0 */ "a.....a" + /* 1 */ "......." + /* 2 */ "......." + /* 3 */ "......." + /* 4 */ "......." + /* 5 */ "a.....a" + /* 6 */ "......." + + // Level 2 + /* z\x* 0123456 */ + /* 0 */ "a.....a" + /* 1 */ "......." + /* 2 */ "......." + /* 3 */ "......." + /* 4 */ "......." + /* 5 */ "a.....a" + /* 6 */ "efefefe" + + // Level 3 + /* z\x* 0123456 */ + /* 0 */ "efefefe" + /* 1 */ "......." + /* 2 */ "......." + /* 3 */ "......." + /* 4 */ "......." + /* 5 */ "efefefe" + /* 6 */ "......." + + // Level 4 + /* z\x* 0123456 */ + /* 0 */ "......." + /* 1 */ "efefefe" + /* 2 */ "efefefe" + /* 3 */ "efefefe" + /* 4 */ "efefefe" + /* 5 */ "......." + /* 6 */ ".......", + + // 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, + }, // 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: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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, + }, // 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/VillageGen.cpp b/src/Generating/VillageGen.cpp index 520d63029..862aa966f 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -7,6 +7,7 @@ #include "VillageGen.h" #include "Prefabs/PlainsVillagePrefabs.h" #include "Prefabs/SandVillagePrefabs.h" +#include "Prefabs/SandFlatRoofVillagePrefabs.h" #include "PieceGenerator.h" @@ -25,8 +26,8 @@ the roads and houses are then used as the following pieces. Only the houses are 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 "1". The houses have connectors of type "-1". The roads have connectors of -both types, type "-1" at the far ends and type "1" on the long edges. +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. 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 @@ -220,7 +221,10 @@ protected: // cVillageGen: /** The prefabs for the sand village. */ -static cVillagePiecePool g_SandVillage (g_SandVillagePrefabs, g_SandVillagePrefabsCount, g_SandVillageStartingPrefabs, g_SandVillageStartingPrefabsCount); +static cVillagePiecePool g_SandVillage(g_SandVillagePrefabs, g_SandVillagePrefabsCount, g_SandVillageStartingPrefabs, g_SandVillageStartingPrefabsCount); + +/** The prefabs for the flat-roofed sand village. */ +static cVillagePiecePool g_SandFlatRoofVillage(g_SandFlatRoofVillagePrefabs, g_SandFlatRoofVillagePrefabsCount, g_SandFlatRoofVillageStartingPrefabs, g_SandFlatRoofVillageStartingPrefabsCount); /** The prefabs for the plains village. */ static cVillagePiecePool g_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVillagePrefabsCount, g_PlainsVillageStartingPrefabs, g_PlainsVillageStartingPrefabsCount); @@ -254,6 +258,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ // 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; + int rnd = (a_OriginX + 21 * a_OriginZ + 985) / 11; for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++) { switch (Biomes[i]) @@ -262,7 +267,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ case biDesertM: { // These biomes allow sand villages - VillagePrefabs = &g_SandVillage; + VillagePrefabs = (rnd % 2 == 0) ? &g_SandVillage : &g_SandFlatRoofVillage; RoadBlock = E_BLOCK_SANDSTONE; break; } From 85fc0dbd97bbf72ba98dfb69351d5c8fa6a8ddfd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 21 May 2014 23:17:09 +0200 Subject: [PATCH 094/312] Changed desert village roads to gravel. --- src/Generating/VillageGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index 862aa966f..a899d5837 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -268,7 +268,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ { // These biomes allow sand villages VillagePrefabs = (rnd % 2 == 0) ? &g_SandVillage : &g_SandFlatRoofVillage; - RoadBlock = E_BLOCK_SANDSTONE; + // RoadBlock = E_BLOCK_SANDSTONE; break; } case biPlains: From ebb1ef237a23ca1bd381afe0a19178e1c1af62ca Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 22 May 2014 08:57:57 +0200 Subject: [PATCH 095/312] Updated plains village prefabs. The DoublePlantBed had sponges in wrong places, plus a few cosmetic fixes. --- .../Prefabs/PlainsVillagePrefabs.cpp | 87 +++++++++---------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp index 863720ab4..22aae5958 100644 --- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -302,28 +302,28 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 0 /* z\x* 11111 */ /* * 012345678901234 */ - /* 0 */ "aaaaaaamaaaaaaa" - /* 1 */ "abbcbbamabbcbba" - /* 2 */ "abbcbbamabbcbba" - /* 3 */ "abbcbbamabbcbba" - /* 4 */ "abbcbbamabbcbba" - /* 5 */ "abbcbbamabbcbba" - /* 6 */ "abbcbbamabbcbba" - /* 7 */ "abbcbbamabbcbba" - /* 8 */ "aaaaaaamaaaaaaa" + /* 0 */ "aaaaaaa.aaaaaaa" + /* 1 */ "abbcbba.abbcbba" + /* 2 */ "abbcbba.abbcbba" + /* 3 */ "abbcbba.abbcbba" + /* 4 */ "abbcbba.abbcbba" + /* 5 */ "abbcbba.abbcbba" + /* 6 */ "abbcbba.abbcbba" + /* 7 */ "abbcbba.abbcbba" + /* 8 */ "aaaaaaa.aaaaaaa" // Level 1 /* z\x* 11111 */ /* * 012345678901234 */ - /* 0 */ "dmmmmmdmdmmmmmd" - /* 1 */ "meemeemmmeemeem" - /* 2 */ "memmmemmmeemeem" - /* 3 */ "memmmmmmmeemeem" - /* 4 */ "meemmemmmeemeem" - /* 5 */ "meemmemmmeemeem" - /* 6 */ "mmemmemmmeemeem" - /* 7 */ "mmememmmmeemeem" - /* 8 */ "dmmmmmdmdmmmmmd", + /* 0 */ "d.....d.d.....d" + /* 1 */ ".ee.ee...ee.ee." + /* 2 */ ".e...e...ee.ee." + /* 3 */ ".e.......ee.ee." + /* 4 */ ".ee..e...ee.ee." + /* 5 */ ".ee..e...ee.ee." + /* 6 */ "..e..e...ee.ee." + /* 7 */ "..e.e....ee.ee." + /* 8 */ "d.....d.d.....d", // Connectors: "-1: 7, 0, 8: 3\n" /* Type -1, direction Z+ */, @@ -779,7 +779,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 8 */ "uh...hv" /* 9 */ "uh...hv" /* 10 */ "uh...hv" - /* 11 */ "ughhhhv" + /* 11 */ "ughhhgv" /* 12 */ "uw...xv" // Level 6 @@ -901,7 +901,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 2 */ "uhDDDhv" /* 3 */ "uhDDDhv" /* 4 */ "uhDDDhv" - /* 5 */ "uhhhhhv" + /* 5 */ "ughhhgv" /* 6 */ "uw...xv" /* 7 */ "......." /* 8 */ "......." @@ -1893,16 +1893,15 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "k: 85: 0\n" /* fence */ "l: 53: 0\n" /* woodstairs */ "m: 19: 0\n" /* sponge */ - "n: 64: 6\n" /* wooddoorblock */ + "n: 64: 2\n" /* wooddoorblock */ "o: 64: 0\n" /* wooddoorblock */ "p:102: 0\n" /* glasspane */ "q: 72: 0\n" /* woodplate */ - "r: 64:12\n" /* wooddoorblock */ - "s: 64: 8\n" /* wooddoorblock */ - "t: 53: 5\n" /* woodstairs */ - "u: 53: 4\n" /* woodstairs */ - "v: 50: 1\n" /* torch */ - "w: 50: 2\n" /* torch */, + "r: 64: 8\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 @@ -1973,7 +1972,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 2 */ ".p.q.pmmmm" /* 3 */ ".p...p...." /* 4 */ ".d...d...." - /* 5 */ ".r...s...." + /* 5 */ ".r...r...." /* 6 */ ".d...d...." /* 7 */ ".p...p...." /* 8 */ ".p...p...." @@ -1983,22 +1982,22 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 5 /* z\x* */ /* * 0123456789 */ - /* 0 */ "lt...ujmmm" + /* 0 */ "ls...tjmmm" /* 1 */ "lidddijmmm" /* 2 */ "ld...djmmm" /* 3 */ "ld...dj..." - /* 4 */ "ldv.wdj..." + /* 4 */ "ldu.vdj..." /* 5 */ "ld...dj..." - /* 6 */ "ldv.wdj..." + /* 6 */ "ldu.vdj..." /* 7 */ "ld...dj..." /* 8 */ "ld...dj..." /* 9 */ "lidddijmmm" - /* 10 */ "lt...ujmmm" + /* 10 */ "ls...tjmmm" // Level 6 /* z\x* */ /* * 0123456789 */ - /* 0 */ "mlt.ujmmmm" + /* 0 */ "mls.tjmmmm" /* 1 */ "mldddjmmmm" /* 2 */ "mld.djmmmm" /* 3 */ "mld.djm..." @@ -2008,7 +2007,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 7 */ "mld.djm..." /* 8 */ "mld.djm..." /* 9 */ "mldddjmmmm" - /* 10 */ "mlt.ujmmmm" + /* 10 */ "mls.tjmmmm" // Level 7 /* z\x* */ @@ -3052,16 +3051,16 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 3 */ "lllllllllllll..." /* 4 */ "eeeeeeeeeeeen..." /* 5 */ "qqqqqqqqqqren..." - /* 6 */ "mmmmmmmmmmren..." - /* 7 */ "mmmmmmmmmmren..." - /* 8 */ "mmmmmmmmmmren..." - /* 9 */ "mmmmmmmmmmren..." - /* 10 */ "mmmmmmmmmmren..." - /* 11 */ "mmmmmmmmmmren..." - /* 12 */ "mmmmmmmmmmren..." - /* 13 */ "mmmmmmmmmmren..." - /* 14 */ "mmmmmmmmmmren..." - /* 15 */ "mmmmmmmmmmren...", + /* 6 */ "..........ren..." + /* 7 */ "..........ren..." + /* 8 */ "mmmmmmmm..ren..." + /* 9 */ "mmmmmmmm..ren..." + /* 10 */ "mmmmmmmm..ren..." + /* 11 */ "mmmmmmmm..ren..." + /* 12 */ "mmmmmmmm..ren..." + /* 13 */ "mmmmmmmm..ren..." + /* 14 */ "mmmmmmmm..ren..." + /* 15 */ "mmmmmmmm..ren...", // Connectors: "-1: 9, 0, 0: 2\n" /* Type -1, direction Z- */, From 6aa7df367f8db7506a8a5ab853c26e3c9fd60253 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 22 May 2014 21:47:56 +0200 Subject: [PATCH 096/312] Villages have min and max density setting. Also made roads use 3+9 scheme, instead of 3+5, for the house connectors. Fixes #1020. --- src/Generating/ComposableGenerator.cpp | 10 +-- src/Generating/PieceGenerator.cpp | 9 +++ src/Generating/PieceGenerator.h | 5 ++ src/Generating/VillageGen.cpp | 92 ++++++++++++++++++++++---- src/Generating/VillageGen.h | 11 ++- 5 files changed, 110 insertions(+), 17 deletions(-) diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index f264599c9..4dd626ed4 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -408,10 +408,12 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) } else if (NoCaseCompare(*itr, "Villages") == 0) { - int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384); - int MaxDepth = a_IniFile.GetValueSetI("Generator", "VillageMaxDepth", 3); - int MaxSize = a_IniFile.GetValueSetI("Generator", "VillageMaxSize", 128); - m_FinishGens.push_back(new cVillageGen(Seed, GridSize, MaxDepth, MaxSize, *m_BiomeGen, *m_HeightGen)); + int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384); + 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, MaxDepth, MaxSize, MinDensity, MaxDensity, *m_BiomeGen, *m_HeightGen)); } else if (NoCaseCompare(*itr, "WaterLakes") == 0) { diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index c12559d3f..7d478f1a1 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -308,6 +308,15 @@ cPiece::cConnector cPlacedPiece::GetRotatedConnector(size_t a_Index) const +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); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPieceGenerator: diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 643ca58b6..e396643a9 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. */ @@ -151,6 +152,10 @@ public: 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; + protected: const cPlacedPiece * m_Parent; const cPiece * m_Piece; diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index a899d5837..bcce62af5 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -27,11 +27,16 @@ though, the roads are generated by code and their content is ignored. A special 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. +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 : @@ -46,7 +51,7 @@ public: super(a_PieceDefs, a_NumPieceDefs, a_StartingPieceDefs, a_NumStartingPieceDefs) { // Add the road pieces: - for (int len = 19; len < 60; len += 8) + for (int len = 27; len < 60; len += 12) { cBlockArea BA; BA.Create(len, 1, 3, cBlockArea::baTypes | cBlockArea::baMetas); @@ -56,14 +61,14 @@ public: RoadPiece->AddConnector(len - 1, 0, 1, BLOCK_FACE_XP, -2); // Add the road connectors: - for (int x = 1; x < len; x += 8) + 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 = 5; x < len; x += 8) + 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); @@ -94,7 +99,8 @@ public: class cVillageGen::cVillage : - public cGridStructGen::cStructure + public cGridStructGen::cStructure, + protected cPiecePool { typedef cGridStructGen::cStructure super; @@ -104,7 +110,8 @@ public: int a_OriginX, int a_OriginZ, int a_MaxRoadDepth, int a_MaxSize, - cPrefabPiecePool & a_Prefabs, + int a_Density, + cPiecePool & a_Prefabs, cTerrainHeightGen & a_HeightGen, BLOCKTYPE a_RoadBlock ) : @@ -112,12 +119,13 @@ public: 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) { - cBFSPieceGenerator pg(m_Prefabs, a_Seed); + cBFSPieceGenerator pg(*this, a_Seed); // Generate the pieces at very negative Y coords, so that we can later test // Piece has negative Y coord -> hasn't been height-adjusted yet pg.PlacePieces(a_OriginX, -1000, a_OriginZ, a_MaxRoadDepth + 1, m_Pieces); @@ -133,11 +141,14 @@ protected: /** 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 */ - cPrefabPiecePool & m_Prefabs; + cPiecePool & m_Prefabs; /** The underlying height generator, used for placing the structures on top of the terrain. */ cTerrainHeightGen & m_HeightGen; @@ -149,7 +160,7 @@ protected: BLOCKTYPE m_RoadBlock; - // cGrdStructGen::cStructure overrides: + // cGridStructGen::cStructure overrides: virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override { // Iterate over all items @@ -211,6 +222,49 @@ protected: } } } + + + // 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 void PiecePlaced(const cPiece & a_Piece) override + { + m_Prefabs.PiecePlaced(a_Piece); + } + + virtual void Reset(void) override + { + m_Prefabs.Reset(); + } } ; @@ -233,10 +287,13 @@ static cVillagePiecePool g_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVillage -cVillageGen::cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen) : +cVillageGen::cVillageGen(int a_Seed, int a_GridSize, 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_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) { @@ -258,7 +315,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ // 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; - int rnd = (a_OriginX + 21 * a_OriginZ + 985) / 11; + int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 11; for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++) { switch (Biomes[i]) @@ -288,12 +345,23 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ } // 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_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, *VillagePrefabs, m_HeightGen, RoadBlock)); + return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *VillagePrefabs, m_HeightGen, RoadBlock)); } diff --git a/src/Generating/VillageGen.h b/src/Generating/VillageGen.h index c6f8f024a..5faaae8a6 100644 --- a/src/Generating/VillageGen.h +++ b/src/Generating/VillageGen.h @@ -21,16 +21,25 @@ class cVillageGen : { typedef cGridStructGen super; public: - cVillageGen(int a_Seed, int a_GridSize, int a_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen, cTerrainHeightGen & a_HeightGen); + cVillageGen(int a_Seed, int a_GridSize, 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; From da843a18811546ca51600a0f3e4438ae4ac5dee8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 22 May 2014 22:19:44 +0200 Subject: [PATCH 097/312] Updated plains village prefabs. Expanded the hitboxes so that houses don't touch each other. Fixed minor visual defects. --- .../Prefabs/PlainsVillagePrefabs.cpp | 367 +++++++++--------- 1 file changed, 176 insertions(+), 191 deletions(-) diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp index 22aae5958..28488be14 100644 --- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -135,8 +135,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 12, 8, 7, // SizeX = 12, SizeY = 8, SizeZ = 7 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 11, 7, 6, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 12, 7, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -357,8 +357,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 12, 10, 11, // SizeX = 12, SizeY = 10, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 11, 9, 10, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 12, 9, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -649,8 +649,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 7, 16, 13, // SizeX = 7, SizeY = 16, SizeZ = 13 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 6, 15, 12, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 7, 15, 13, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -974,8 +974,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 7, 8, 9, // SizeX = 7, SizeY = 8, SizeZ = 9 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 6, 7, 8, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 7, 7, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1127,8 +1127,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 12, 9, 9, // SizeX = 12, SizeY = 9, SizeZ = 9 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 11, 8, 8, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 12, 8, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1308,8 +1308,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 7, 8, 7, // SizeX = 7, SizeY = 8, SizeZ = 7 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 6, 7, 6, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 7, 7, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1444,8 +1444,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 9, 8, 7, // SizeX = 9, SizeY = 8, SizeZ = 7 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 8, 7, 6, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 9, 7, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1580,8 +1580,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 11, 8, 7, // SizeX = 11, SizeY = 8, SizeZ = 7 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 7, 6, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 7, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1724,8 +1724,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 11, 8, 7, // SizeX = 11, SizeY = 8, SizeZ = 7 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 7, 6, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 7, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1872,18 +1872,18 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 9, ID 26, created by Aloe_vera { // Size: - 10, 8, 11, // SizeX = 10, SizeY = 8, SizeZ = 11 + 10, 7, 11, // SizeX = 10, SizeY = 7, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 9, 7, 10, // MaxX, MaxY, MaxZ + 0, -1, -1, // MinX, MinY, MinZ + 10, 6, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 4: 0\n" /* cobblestone */ - "d: 5: 0\n" /* wood */ + "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 */ @@ -1907,125 +1907,110 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 0 /* z\x* */ /* * 0123456789 */ - /* 0 */ "aaaaaaaaaa" - /* 1 */ "aaaaaaaaaa" - /* 2 */ "aaaaaaaaaa" - /* 3 */ "aaaaaaaaaa" - /* 4 */ "aaaaaaaaaa" - /* 5 */ "aaaaaaaaaa" - /* 6 */ "aaaaaaaaaa" - /* 7 */ "aaaaaaaaaa" - /* 8 */ "aaaaaaaaaa" - /* 9 */ "aaaaaaaaaa" - /* 10 */ "aaaaaaaaaa" + /* 0 */ "mmmmmmmmmm" + /* 1 */ "maaaaammmm" + /* 2 */ "maaaaammmm" + /* 3 */ "maaaaabbbb" + /* 4 */ "aaaaaabbbb" + /* 5 */ "aaaaaabbbb" + /* 6 */ "aaaaaabbbb" + /* 7 */ "maaaaabbbb" + /* 8 */ "maaaaabbbb" + /* 9 */ "maaaaammmm" + /* 10 */ "mmmmmmmmmm" // Level 1 /* z\x* */ /* * 0123456789 */ - /* 0 */ "bbbbbbbbbb" - /* 1 */ "baaaaabbbb" - /* 2 */ "baaaaabbbb" - /* 3 */ "baaaaaaaaa" - /* 4 */ "aaaaaaaaaa" - /* 5 */ "aaaaaaaaaa" - /* 6 */ "aaaaaaaaaa" - /* 7 */ "baaaaaaaaa" - /* 8 */ "baaaaaaaaa" - /* 9 */ "baaaaabbbb" - /* 10 */ "bbbbbbbbbb" + /* 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 */ ".cccccmmmm" - /* 2 */ ".cdddcmmmm" - /* 3 */ ".cdddcbbbb" - /* 4 */ "ecfffcbbbb" - /* 5 */ "gcffffbbbb" - /* 6 */ "hcfffcbbbb" - /* 7 */ ".cfffcbbbb" - /* 8 */ ".cfffcbbbb" - /* 9 */ ".cccccmmmm" + /* 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 */ ".idddimmmm" - /* 2 */ ".djkldmmmm" - /* 3 */ ".d...dkkkk" - /* 4 */ ".d...d...k" - /* 5 */ ".n...o...k" - /* 6 */ ".d...d...k" - /* 7 */ ".dff.d...k" - /* 8 */ ".d...dkkkk" - /* 9 */ ".idddimmmm" - /* 10 */ "......mmmm" - - // Level 4 - /* z\x* */ - /* * 0123456789 */ - /* 0 */ "......mmmm" /* 1 */ ".ipppimmmm" /* 2 */ ".p.q.pmmmm" /* 3 */ ".p...p...." - /* 4 */ ".d...d...." + /* 4 */ ".c...c...." /* 5 */ ".r...r...." - /* 6 */ ".d...d...." + /* 6 */ ".c...c...." /* 7 */ ".p...p...." /* 8 */ ".p...p...." /* 9 */ ".ipppimmmm" /* 10 */ "......mmmm" - // Level 5 + // Level 4 /* z\x* */ /* * 0123456789 */ /* 0 */ "ls...tjmmm" - /* 1 */ "lidddijmmm" - /* 2 */ "ld...djmmm" - /* 3 */ "ld...dj..." - /* 4 */ "ldu.vdj..." - /* 5 */ "ld...dj..." - /* 6 */ "ldu.vdj..." - /* 7 */ "ld...dj..." - /* 8 */ "ld...dj..." - /* 9 */ "lidddijmmm" + /* 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 */ "mls.tjmmmm" - /* 1 */ "mldddjmmmm" - /* 2 */ "mld.djmmmm" - /* 3 */ "mld.djm..." - /* 4 */ "mld.djm..." - /* 5 */ "mld.djm..." - /* 6 */ "mld.djm..." - /* 7 */ "mld.djm..." - /* 8 */ "mld.djm..." - /* 9 */ "mldddjmmmm" - /* 10 */ "mls.tjmmmm" - - // Level 7 - /* z\x* */ - /* * 0123456789 */ - /* 0 */ "mmldjmmmmm" - /* 1 */ "mmldjmmmmm" - /* 2 */ "mmldjmmmmm" - /* 3 */ "mmldjmm..." - /* 4 */ "mmldjmm..." - /* 5 */ "mmldjmm..." - /* 6 */ "mmldjmm..." - /* 7 */ "mmldjmm..." - /* 8 */ "mmldjmm..." - /* 9 */ "mmldjmmmmm" - /* 10 */ "mmldjmmmmm", + /* 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, 2, 5: 4\n" /* Type -1, direction X- */, + "-1: 0, 1, 5: 4\n" /* Type -1, direction X- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2056,8 +2041,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 11, 9, 9, // SizeX = 11, SizeY = 9, SizeZ = 9 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 8, 8, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 8, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -2230,17 +2215,17 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 11, 9, 13, // SizeX = 11, SizeY = 9, SizeZ = 13 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 8, 12, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 8, 13, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ "a: 3: 0\n" /* dirt */ "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ + "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 */ @@ -2262,52 +2247,52 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "aaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaa" + /* 1 */ "aaaaaaaaaab" + /* 2 */ "aaaaaaaaaab" + /* 3 */ "aaaaaaaaaab" + /* 4 */ "aaaaaaaaaab" /* 5 */ "aaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaa" - /* 7 */ "aaaaaaaaaaa" - /* 8 */ "aaaaaaaaaaa" - /* 9 */ "aaaaaaaaaaa" - /* 10 */ "aaaaaaaaaaa" - /* 11 */ "aaaaaaaaaaa" - /* 12 */ "aaaaaaaaaaa" + /* 6 */ "aaaaaaaaaab" + /* 7 */ "aaaaaaaaaab" + /* 8 */ "abaaaaaaabb" + /* 9 */ "aaaaaaaaabb" + /* 10 */ "aaaaaaaaabb" + /* 11 */ "abaaaaaaaba" + /* 12 */ "abaaaaaaabb" // Level 1 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "bbbbaaabbbb" - /* 1 */ "baaaaaaaaab" - /* 2 */ "baaaaaaaaab" - /* 3 */ "baaaaaaaaab" - /* 4 */ "baaaaaaaaab" - /* 5 */ "baaaaaaaaab" - /* 6 */ "baaaaaaaaab" - /* 7 */ "baaaaaaaaab" - /* 8 */ "bbaaaaaaabb" - /* 9 */ "bbaaaaaaabb" - /* 10 */ "bbaaaaaaabb" - /* 11 */ "bbaaaaaaabb" - /* 12 */ "bbaaaaaaabb" + /* 0 */ "mmmmcccmmmm" + /* 1 */ "mcccccccccm" + /* 2 */ "mcccccccccm" + /* 3 */ "mcccccccccm" + /* 4 */ "mcccccccccm" + /* 5 */ "mcccccccccm" + /* 6 */ "mcccccccccm" + /* 7 */ "mcccccccccm" + /* 8 */ "mmaaaaaaamm" + /* 9 */ "mmaaaaaaamm" + /* 10 */ "mmaaaaaaamm" + /* 11 */ "mmaaaaaaamm" + /* 12 */ "mmaaaaaaamm" // Level 2 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "....cde...." - /* 1 */ ".fffffffff." - /* 2 */ ".fggggffff." - /* 3 */ ".fggggffff." - /* 4 */ ".fggggffff." - /* 5 */ ".fggggffff." - /* 6 */ ".fggggffff." - /* 7 */ ".fffffffff." + /* 0 */ "....def...." + /* 1 */ ".ccccccccc." + /* 2 */ ".cggggcccc." + /* 3 */ ".cggggcccc." + /* 4 */ ".cggggcccc." + /* 5 */ ".cggggcccc." + /* 6 */ ".cggggcccc." + /* 7 */ ".ccccccccc." /* 8 */ "..bbbbbbb.." - /* 9 */ "mmbbbbbbbmm" - /* 10 */ "mmbbbbbbbmm" - /* 11 */ "mmbbbbbbbmm" - /* 12 */ "mmbbbbbbbmm" + /* 9 */ "..bbbbbbb.." + /* 10 */ "..bbbbbbb.." + /* 11 */ "..bbbbbbb.." + /* 12 */ "..bbbbbbb.." // Level 3 /* z\x* 1 */ @@ -2321,10 +2306,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ ".i.......i." /* 7 */ ".hiiijiiih." /* 8 */ "..l.....l.." - /* 9 */ "mml.....lmm" - /* 10 */ "mml.....lmm" - /* 11 */ "mml.....lmm" - /* 12 */ "mmlllllllmm" + /* 9 */ "..l.....l.." + /* 10 */ "..l.....l.." + /* 11 */ "..l.....l.." + /* 12 */ "..lllllll.." // Level 4 /* z\x* 1 */ @@ -2338,10 +2323,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ ".o.......o." /* 7 */ ".hooipiooh." /* 8 */ "..........." - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm" + /* 9 */ "..........." + /* 10 */ "..........." + /* 11 */ "..........." + /* 12 */ "..........." // Level 5 /* z\x* 1 */ @@ -2355,10 +2340,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ ".i.......i." /* 7 */ "uiiiiiiiiiu" /* 8 */ "kkkkkkkkkkk" - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm" + /* 9 */ "..........." + /* 10 */ "..........." + /* 11 */ "..........." + /* 12 */ "..........." // Level 6 /* z\x* 1 */ @@ -2372,10 +2357,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ "uiiiiiiiiiu" /* 7 */ "kkkkkkkkkkk" /* 8 */ "..........." - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm" + /* 9 */ "..........." + /* 10 */ "..........." + /* 11 */ "..........." + /* 12 */ "..........." // Level 7 /* z\x* 1 */ @@ -2389,10 +2374,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ "kkkkkkkkkkk" /* 7 */ "..........." /* 8 */ "..........." - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm" + /* 9 */ "..........." + /* 10 */ "..........." + /* 11 */ "..........." + /* 12 */ "..........." // Level 8 /* z\x* 1 */ @@ -2406,10 +2391,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 6 */ "..........." /* 7 */ "..........." /* 8 */ "..........." - /* 9 */ "mm.......mm" - /* 10 */ "mm.......mm" - /* 11 */ "mm.......mm" - /* 12 */ "mm.......mm", + /* 9 */ "..........." + /* 10 */ "..........." + /* 11 */ "..........." + /* 12 */ "...........", // Connectors: "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */, @@ -2443,8 +2428,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 11, 9, 9, // SizeX = 11, SizeY = 9, SizeZ = 9 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 8, 8, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 8, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -2620,8 +2605,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 15, 10, 16, // SizeX = 15, SizeY = 10, SizeZ = 16 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 14, 9, 15, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 15, 9, 16, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -2891,8 +2876,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 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 + -1, 0, 0, // MinX, MinY, MinZ + 16, 6, 16, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -3094,8 +3079,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 11, 8, 11, // SizeX = 11, SizeY = 8, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 7, 10, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 7, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -3277,8 +3262,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 15, 8, 11, // SizeX = 15, SizeY = 8, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 14, 7, 10, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 15, 7, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -3458,7 +3443,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 9, 18, 13, // SizeX = 9, SizeY = 18, SizeZ = 13 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ + -1, 0, 0, // MinX, MinY, MinZ 8, 17, 12, // MaxX, MaxY, MaxZ // Block definitions: @@ -3808,8 +3793,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = 15, 10, 9, // SizeX = 15, SizeY = 10, SizeZ = 9 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 14, 9, 8, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 15, 9, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ From f03cbb5e04d8dc4ccbb51cf63200ff3ac597f0f9 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 23 May 2014 11:22:48 +0200 Subject: [PATCH 098/312] Fixed profiling flags for MSVC. The profiler output contained no useful symbols before, because there were no symbols in the PDBs. --- SetFlags.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index 4eed529bd..fe867f9af 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -118,8 +118,8 @@ endmacro() macro(enable_profile) # Declare the flags used for profiling builds: if (MSVC) - set (CXX_PROFILING "") - set (LNK_PROFILING "/PROFILE") + set (CXX_PROFILING "/Zi") + set (LNK_PROFILING "/PROFILE /DEBUG") else() set (CXX_PROFILING "-pg") set (LNK_PROFILING "-pg") From 941cb88ae456f0d8b91f6b5dc835c2536eef15f6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 23 May 2014 12:33:30 +0200 Subject: [PATCH 099/312] Fixed datatype conversion warning. --- src/Entities/Entity.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 15f456332..2567b7adc 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1018,10 +1018,10 @@ void cEntity::TickInVoid(cChunk & a_Chunk) -void cEntity::DetectCacti() +void cEntity::DetectCacti(void) { int X = POSX_TOINT, Y = POSY_TOINT, Z = POSZ_TOINT; - float w = m_Width / 2; + double w = m_Width / 2; if ( (((X + 1) - GetPosX() < w) && (GetWorld()->GetBlock(X + 1, Y, Z) == E_BLOCK_CACTUS)) || (((GetPosX() - (X - 1)) - 1 < w) && (GetWorld()->GetBlock(X - 1, Y, Z) == E_BLOCK_CACTUS)) || From a4c964c888748e7099308dc56578244112148cdd Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 23 May 2014 13:01:06 +0200 Subject: [PATCH 100/312] Auto-enlargement for cGridStructGen cache. --- src/Generating/GridStructGen.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp index 3bbc89054..bfa6bccb1 100644 --- a/src/Generating/GridStructGen.cpp +++ b/src/Generating/GridStructGen.cpp @@ -22,6 +22,15 @@ cGridStructGen::cGridStructGen( m_MaxStructureSizeZ(a_MaxStructureSizeZ), m_MaxCacheSize(a_MaxCacheSize) { + size_t NumStructuresPerQuery = (size_t)((m_MaxStructureSizeX / m_GridSizeX + 1) * (m_MaxStructureSizeZ / m_GridSizeZ + 1)); + if (NumStructuresPerQuery > m_MaxCacheSize) + { + m_MaxCacheSize = NumStructuresPerQuery * 4; + LOGINFO( + "cGridStructGen: The cache size is too small (%u), increasing the cache size to %u to avoid inefficiency.", + (unsigned)a_MaxCacheSize, (unsigned)m_MaxCacheSize + ); + } } From 97865bff7ce1595ae43be65082c1a02fed4ea8c4 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 23 May 2014 13:01:50 +0200 Subject: [PATCH 101/312] Fixed Mineshaft system size. --- src/Generating/MineShafts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index 391e4c04f..81ae6481d 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -1283,7 +1283,7 @@ cStructGenMineShafts::cStructGenMineShafts( int a_Seed, int a_GridSize, int a_MaxSystemSize, int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase ) : - super(a_Seed, a_GridSize, a_GridSize, 120 + a_MaxSystemSize * 10, 120 + a_MaxSystemSize * 10, 100), + super(a_Seed, a_GridSize, a_GridSize, a_MaxSystemSize, a_MaxSystemSize, 100), m_Noise(a_Seed), m_GridSize(a_GridSize), m_MaxSystemSize(a_MaxSystemSize), From 41692da30c9985ea1b5aa7430cb582997293bdd7 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 23 May 2014 15:01:27 +0100 Subject: [PATCH 102/312] Ignore CTest files --- .gitignore | 1 + 1 file changed, 1 insertion(+) 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 From 8f964886e0ccbf51dac07227f0ac4c739b47d3a5 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 24 May 2014 13:33:40 +0100 Subject: [PATCH 103/312] Implemented style changes --- src/BlockArea.cpp | 2 +- src/Chunk.cpp | 4 +- src/Chunk.h | 4 +- src/ChunkData.cpp | 61 +++++++------- src/ChunkData.h | 120 ++++++++++++++------------- src/ChunkDataCallback.h | 8 +- tests/ChunkData/ArraytoCoord.cpp | 90 +++++++-------------- tests/ChunkData/Coordinates.cpp | 38 ++++----- tests/ChunkData/Copies.cpp | 135 +++++++++---------------------- 9 files changed, 188 insertions(+), 274 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 87236957a..11bd76e6c 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -1908,7 +1908,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) if (m_Area.m_BlockLight != NULL) { - a_BlockBuffer.CopyLight(m_Area.m_BlockLight); + a_BlockBuffer.CopyBlockLight(m_Area.m_BlockLight); } if (m_Area.m_BlockSkyLight != NULL) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index d85b44607..e5f8f1e29 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -284,7 +284,7 @@ void cChunk::SetAllData( m_ChunkData.SetBlocks(a_BlockTypes); m_ChunkData.SetMeta(a_BlockMeta); - m_ChunkData.SetLight(a_BlockLight); + m_ChunkData.SetBlockLight(a_BlockLight); m_ChunkData.SetSkyLight(a_BlockSkyLight); m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL); @@ -326,7 +326,7 @@ 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 :) - m_ChunkData.SetLight(a_BlockLight); + m_ChunkData.SetBlockLight(a_BlockLight); m_ChunkData.SetSkyLight(a_SkyLight); diff --git a/src/Chunk.h b/src/Chunk.h index 2de45919e..d95537acf 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -67,7 +67,7 @@ public: cChunkMap * a_ChunkMap, cWorld * a_World, // Parent objects cChunk * a_NeighborXM, cChunk * a_NeighborXP, cChunk * a_NeighborZM, cChunk * a_NeighborZP // Neighbor chunks ); - cChunk(cChunk& other); + cChunk(cChunk & other); ~cChunk(); bool IsValid(void) const {return m_IsValid; } // Returns true if the chunk block data is valid (loaded / generated) @@ -156,7 +156,7 @@ public: 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. BLOCKTYPE GetBlock(int a_RelX, int a_RelY, int a_RelZ) const; - BLOCKTYPE GetBlock(Vector3i a_cords) const { return GetBlock(a_cords.x,a_cords.y,a_cords.z);} + 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); diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 86b0c431c..098f436f8 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -5,7 +5,7 @@ cChunkData cChunkData::Copy() const { cChunkData copy; - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { if (m_Sections[i] != NULL) { @@ -22,13 +22,16 @@ cChunkData cChunkData::Copy() const void cChunkData::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) const { - for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; - if (a_Idx > 0) a_Idx = a_Idx > length ? a_Idx - length : 0; + if (a_Idx > 0) + { + a_Idx = std::max(a_Idx - length, (size_t) 0); + } if (a_Idx == 0) { - size_t tocopy = length > segment_length ? segment_length : length; + size_t tocopy = std::min(segment_length, length); length -= tocopy; if (m_Sections[i] != NULL) { @@ -56,7 +59,7 @@ void cChunkData::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) void cChunkData::CopyMeta(NIBBLETYPE * a_dest) const { - for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) @@ -82,9 +85,9 @@ void cChunkData::CopyMeta(NIBBLETYPE * a_dest) const -void cChunkData::CopyLight(NIBBLETYPE * a_dest) const +void cChunkData::CopyBlockLight(NIBBLETYPE * a_dest) const { - for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) @@ -112,7 +115,7 @@ void cChunkData::CopyLight(NIBBLETYPE * a_dest) const void cChunkData::CopySkyLight(NIBBLETYPE * a_dest) const { - for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) @@ -140,7 +143,7 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_dest) const void cChunkData::SetBlocks(const BLOCKTYPE * a_src) { - for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; if (m_Sections[i] != NULL) @@ -153,6 +156,9 @@ void cChunkData::SetBlocks(const BLOCKTYPE * a_src) } else { + // j counts how many of leading zeros the buffer has + // if j == segment_length then the buffer is all zeros so there is no point + // creating the buffer. size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); @@ -180,11 +186,6 @@ void cChunkData::SetBlocks(const BLOCKTYPE * a_src) sizeof(m_Sections[i]->m_BlockSkyLight) ); } - else - { - Free(m_Sections[i]); - m_Sections[i] = 0; - } } } } @@ -194,7 +195,7 @@ void cChunkData::SetBlocks(const BLOCKTYPE * a_src) void cChunkData::SetMeta(const NIBBLETYPE * a_src) { - for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) @@ -207,6 +208,9 @@ void cChunkData::SetMeta(const NIBBLETYPE * a_src) } else { + // j counts how many of leading zeros the buffer has + // if j == segment_length then the buffer is all zeros so there is no point + // creating the buffer. size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); @@ -234,11 +238,6 @@ void cChunkData::SetMeta(const NIBBLETYPE * a_src) sizeof(m_Sections[i]->m_BlockSkyLight) ); } - else - { - Free(m_Sections[i]); - m_Sections[i] = 0; - } } } } @@ -246,10 +245,10 @@ void cChunkData::SetMeta(const NIBBLETYPE * a_src) -void cChunkData::SetLight(const NIBBLETYPE * a_src) +void cChunkData::SetBlockLight(const NIBBLETYPE * a_src) { if (!a_src) return; - for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) @@ -262,6 +261,9 @@ void cChunkData::SetLight(const NIBBLETYPE * a_src) } else { + // j counts how many of leading zeros the buffer has + // if j == segment_length then the buffer is all zeros so there is no point + // creating the buffer. size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); @@ -289,11 +291,6 @@ void cChunkData::SetLight(const NIBBLETYPE * a_src) sizeof(m_Sections[i]->m_BlockSkyLight) ); } - else - { - Free(m_Sections[i]); - m_Sections[i] = 0; - } } } } @@ -304,7 +301,7 @@ void cChunkData::SetLight(const NIBBLETYPE * a_src) void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) { if (!a_src) return; - for (size_t i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) @@ -317,6 +314,9 @@ void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) } else { + // j counts how many of leading zeros the buffer has + // if j == segment_length then the buffer is all zeros so there is no point + // creating the buffer. size_t j = 0; // do nothing whilst 0 for (; j < segment_length && a_src[i * segment_length + j] == 0xFF; j++); @@ -344,11 +344,6 @@ void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) sizeof(m_Sections[i]->m_BlockLight) ); } - else - { - Free(m_Sections[i]); - m_Sections[i] = 0; - } } } } diff --git a/src/ChunkData.h b/src/ChunkData.h index 9c852ee24..5a149f95f 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -8,8 +8,7 @@ #include "ChunkDef.h" -#define CHUNK_SECTION_HEIGHT 16 -#define CHUNK_SECTION_NUM (256 / CHUNK_SECTION_HEIGHT) + #if __cplusplus < 201103L // auto_ptr style interface for memory management @@ -23,8 +22,8 @@ public: cChunkData() #if __cplusplus < 201103L - // auto_ptr style interface for memory management - : IsOwner(true) + // auto_ptr style interface for memory management + : IsOwner(true) #endif { memset(m_Sections, 0, sizeof(m_Sections)); @@ -32,72 +31,75 @@ public: ~cChunkData() { #if __cplusplus < 201103L - // auto_ptr style interface for memory management - if (!IsOwner) return; + // auto_ptr style interface for memory management + if (!IsOwner) + { + return; + } #endif - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { if (m_Sections[i] == NULL) Free(m_Sections[i]);; } } #if __cplusplus < 201103L - // auto_ptr style interface for memory management - cChunkData(const cChunkData& other) : - IsOwner(true) - { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + // auto_ptr style interface for memory management + cChunkData(const cChunkData& other) : + IsOwner(true) { - m_Sections[i] = other.m_Sections[i]; - } - other.IsOwner = false; - } - - cChunkData& operator=(const cChunkData& other) - { - if (&other != this) - { - if (IsOwner) - { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) - { - if (m_Sections[i]) Free(m_Sections[i]);; - } - } - IsOwner = true; - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { m_Sections[i] = other.m_Sections[i]; } other.IsOwner = false; } - return *this; - - } - #else - // unique_ptr style interface for memory management - cChunkData(cChunkData&& other) - { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + + cChunkData& operator=(const cChunkData& other) { - m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = 0; - } - } - - cChunkData& operator=(cChunkData&& other) - { - if (&other != this) - { - for (int i = 0; i < CHUNK_SECTION_NUM; i++) + if (&other != this) + { + if (IsOwner) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + if (m_Sections[i]) Free(m_Sections[i]);; + } + } + IsOwner = true; + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + m_Sections[i] = other.m_Sections[i]; + } + other.IsOwner = false; + } + return *this; + + } + #else + // unique_ptr style interface for memory management + cChunkData(cChunkData&& other) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - Free(m_Sections[i]);; m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = 0; + other.m_Sections[i] = NULL; } } - return *this; - } + + cChunkData& operator=(cChunkData&& other) + { + if (&other != this) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + Free(m_Sections[i]);; + m_Sections[i] = other.m_Sections[i]; + other.m_Sections[i] = NULL; + } + } + return *this; + } #endif BLOCKTYPE GetBlock(int a_X, int a_Y, int a_Z) const @@ -150,7 +152,10 @@ public: NIBBLETYPE 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)) + 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 / CHUNK_SECTION_HEIGHT; if (m_Sections[Section] != NULL) @@ -244,16 +249,19 @@ public: cChunkData Copy() const; void CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx = 0, size_t length = cChunkDef::NumBlocks) const; void CopyMeta (NIBBLETYPE * a_dest) const; - void CopyLight (NIBBLETYPE * a_dest) const; + void CopyBlockLight (NIBBLETYPE * a_dest) const; void CopySkyLight (NIBBLETYPE * a_dest) const; void SetBlocks (const BLOCKTYPE * a_src); void SetMeta (const NIBBLETYPE * a_src); - void SetLight (const NIBBLETYPE * a_src); + void SetBlockLight (const NIBBLETYPE * a_src); void SetSkyLight (const NIBBLETYPE * a_src); private: + static const size_t CHUNK_SECTION_HEIGHT = 16; + static const size_t CHUNK_SECTION_COUNT = (256 / CHUNK_SECTION_HEIGHT); + #if __cplusplus < 201103L // auto_ptr style interface for memory management mutable bool IsOwner; @@ -266,7 +274,7 @@ private: NIBBLETYPE m_BlockSkyLight[CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; }; - sChunkSection *m_Sections[CHUNK_SECTION_NUM]; + sChunkSection *m_Sections[CHUNK_SECTION_COUNT]; sChunkSection * Allocate() const; void Free(sChunkSection * ptr) const; diff --git a/src/ChunkDataCallback.h b/src/ChunkDataCallback.h index 340582885..e916d6486 100644 --- a/src/ChunkDataCallback.h +++ b/src/ChunkDataCallback.h @@ -62,7 +62,7 @@ protected: /** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer */ class cChunkDataArrayCollector : -public cChunkDataCallback + public cChunkDataCallback { public: @@ -75,7 +75,7 @@ protected: { a_ChunkBuffer.CopyBlocks(m_BlockData); a_ChunkBuffer.CopyMeta(m_BlockData + cChunkDef::NumBlocks); - a_ChunkBuffer.CopyLight(m_BlockData + 3 * cChunkDef::NumBlocks / 2); + a_ChunkBuffer.CopyBlockLight(m_BlockData + 3 * cChunkDef::NumBlocks / 2); a_ChunkBuffer.CopySkyLight(m_BlockData + 2 * cChunkDef::NumBlocks); } }; @@ -83,7 +83,7 @@ protected: /** A simple implementation of the cChunkDataCallback interface that collects all block data into a separate buffers */ class cChunkDataSeparateCollector : -public cChunkDataCallback + public cChunkDataCallback { public: @@ -98,7 +98,7 @@ protected: { a_ChunkBuffer.CopyBlocks(m_BlockTypes); a_ChunkBuffer.CopyMeta(m_BlockMetas); - a_ChunkBuffer.CopyLight(m_BlockLight); + a_ChunkBuffer.CopyBlockLight(m_BlockLight); a_ChunkBuffer.CopySkyLight(m_BlockSkyLight); } } ; diff --git a/tests/ChunkData/ArraytoCoord.cpp b/tests/ChunkData/ArraytoCoord.cpp index fe82a3a7b..1138fb5b6 100644 --- a/tests/ChunkData/ArraytoCoord.cpp +++ b/tests/ChunkData/ArraytoCoord.cpp @@ -10,107 +10,77 @@ int main(int argc, char** argv) // Test first segment cChunkData buffer; - BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); - SrcBlockBuffer[7+4*16+5*16*16] = 0xCD; + SrcBlockBuffer[7 + (4 * 16) + (5 * 16 * 16)] = 0xCD; buffer.SetBlocks(SrcBlockBuffer); testassert(buffer.GetBlock(7,5,4) == 0xCD); - delete SrcBlockBuffer; - SrcBlockBuffer = NULL; - NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - SrcNibbleBuffer[(6+1*16+2*16*16)/2] = 0xE; + NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); + SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 0xE; buffer.SetMeta(SrcNibbleBuffer); - testassert(buffer.GetMeta(6,2,1) == 0xE); - delete SrcNibbleBuffer; - SrcNibbleBuffer = NULL; + testassert(buffer.GetMeta(6, 2, 1) == 0xE); - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - SrcNibbleBuffer[(6+1*16+2*16*16)/2] = 0xE; - buffer.SetLight(SrcNibbleBuffer); - testassert(buffer.GetBlockLight(6,2,1) == 0xE); - delete SrcNibbleBuffer; - SrcNibbleBuffer = NULL; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); + SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 0xE; + buffer.SetBlockLight(SrcNibbleBuffer); + testassert(buffer.GetBlockLight(6, 2, 1) == 0xE); - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - SrcNibbleBuffer[(6+1*16+2*16*16)/2] = 0xE; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); + SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 0xE; buffer.SetSkyLight(SrcNibbleBuffer); - testassert(buffer.GetSkyLight(6,2,1) == 0xE); - delete SrcNibbleBuffer; - SrcNibbleBuffer = NULL; + testassert(buffer.GetSkyLight(6, 2, 1) == 0xE); } { // test following segment cChunkData buffer; - BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); - SrcBlockBuffer[7+4*16+24*16*16] = 0xCD; + SrcBlockBuffer[7 + (4 * 16) + (24 * 16 * 16)] = 0xCD; buffer.SetBlocks(SrcBlockBuffer); - testassert(buffer.GetBlock(7,24,4) == 0xCD); - delete SrcBlockBuffer; - SrcBlockBuffer = NULL; + testassert(buffer.GetBlock(7, 24, 4) == 0xCD); - NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - SrcNibbleBuffer[(6+1*16+24*16*16)/2] = 0xE; + NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); + SrcNibbleBuffer[(6 + (1 * 16) + (24 * 16 * 16)) / 2] = 0xE; buffer.SetMeta(SrcNibbleBuffer); - testassert(buffer.GetMeta(6,24,1) == 0xE); - delete SrcNibbleBuffer; - SrcNibbleBuffer = NULL; + testassert(buffer.GetMeta(6, 24, 1) == 0xE); - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); SrcNibbleBuffer[(6+1*16+24*16*16)/2] = 0xE; - buffer.SetLight(SrcNibbleBuffer); + buffer.SetBlockLight(SrcNibbleBuffer); testassert(buffer.GetBlockLight(6,24,1) == 0xE); - delete SrcNibbleBuffer; - SrcNibbleBuffer = NULL; - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - SrcNibbleBuffer[(6+1*16+24*16*16)/2] = 0xE; + memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 / 2); + SrcNibbleBuffer[(6 + (1 * 16) + (24 * 16 * 16))/2] = 0xE; buffer.SetSkyLight(SrcNibbleBuffer); - testassert(buffer.GetSkyLight(6,24,1) == 0xE); - delete SrcNibbleBuffer; - SrcNibbleBuffer = NULL; + testassert(buffer.GetSkyLight(6, 24, 1) == 0xE); } { // test zeros cChunkData buffer; - BLOCKTYPE* SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); buffer.SetBlocks(SrcBlockBuffer); - testassert(buffer.GetBlock(7,24,4) == 0x00); - delete SrcBlockBuffer; - SrcBlockBuffer = NULL; + testassert(buffer.GetBlock(7, 24, 4) == 0x00); - NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); buffer.SetMeta(SrcNibbleBuffer); - testassert(buffer.GetMeta(6,24,1) == 0x0); - delete SrcNibbleBuffer; - SrcNibbleBuffer = NULL; + testassert(buffer.GetMeta(6, 24, 1) == 0x0); - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - buffer.SetLight(SrcNibbleBuffer); + buffer.SetBlockLight(SrcNibbleBuffer); testassert(buffer.GetBlockLight(6,24,1) == 0x0); - delete SrcNibbleBuffer; - SrcNibbleBuffer = NULL; - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); buffer.SetSkyLight(SrcNibbleBuffer); - testassert(buffer.GetSkyLight(6,24,1) == 0xF); - delete SrcNibbleBuffer; - SrcNibbleBuffer = NULL; + testassert(buffer.GetSkyLight(6, 24, 1) == 0xF); } } diff --git a/tests/ChunkData/Coordinates.cpp b/tests/ChunkData/Coordinates.cpp index c0c46000e..f02b68d40 100644 --- a/tests/ChunkData/Coordinates.cpp +++ b/tests/ChunkData/Coordinates.cpp @@ -10,18 +10,18 @@ int main(int argc, char** argv) cChunkData buffer; // 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); + 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); + 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); + testassert(buffer.GetBlock(0, 32, 0) == 0x0); + testassert(buffer.GetMeta(0, 48, 0) == 0x0); // Out of Range CheckAsserts( @@ -108,35 +108,35 @@ int main(int argc, char** argv) cChunkData buffer; // 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.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); + 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; - buffer.SetBlock(0,0,0,0x42); + buffer.SetBlock(0, 0, 0, 0x42); cChunkData copy; #if __cplusplus < 201103L copy = buffer; #else copy = std::move(buffer); #endif - testassert(copy.GetBlock(0,0,0) == 0x42); + 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); + testassert(copy.GetBlock(0, 0, 0) == 0x42); } return 0; diff --git a/tests/ChunkData/Copies.cpp b/tests/ChunkData/Copies.cpp index 145ffd8e0..b10ddb759 100644 --- a/tests/ChunkData/Copies.cpp +++ b/tests/ChunkData/Copies.cpp @@ -9,14 +9,14 @@ int main(int argc, char** argv) { cChunkData buffer; - buffer.SetBlock(3,1,4,0xDE); - buffer.SetMeta(3,1,4,0xA); + 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); + testassert(copy.GetBlock(3, 1, 4) == 0xDE); + testassert(copy.GetMeta(3, 1, 4) == 0xA); - BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; for (int i = 0; i < 16 * 16 * 256; i += 4) { SrcBlockBuffer[i+0] = 0xDE; @@ -26,30 +26,20 @@ int main(int argc, char** argv) } buffer.SetBlocks(SrcBlockBuffer); - BLOCKTYPE * DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + BLOCKTYPE DstBlockBuffer[16 * 16 * 256]; buffer.CopyBlocks(DstBlockBuffer); - testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); - delete SrcBlockBuffer; - delete DstBlockBuffer; - SrcBlockBuffer = NULL; - DstBlockBuffer = NULL; + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) - 1) == 0); - SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); buffer.SetBlocks(SrcBlockBuffer); - DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; buffer.CopyBlocks(DstBlockBuffer); - testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); - delete SrcBlockBuffer; - delete DstBlockBuffer; - SrcBlockBuffer = NULL; - DstBlockBuffer = NULL; + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) - 1) == 0); } { cChunkData buffer; - NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) { SrcNibbleBuffer[i+0] = 0xEF; @@ -59,30 +49,21 @@ int main(int argc, char** argv) } buffer.SetMeta(SrcNibbleBuffer); - NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + NIBBLETYPE DstNibbleBuffer[16 * 16 * 256/ 2]; buffer.CopyMeta(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); buffer.SetMeta(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; buffer.CopyMeta(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); + } { cChunkData buffer; - NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) { SrcNibbleBuffer[i+0] = 0xDE; @@ -91,32 +72,22 @@ int main(int argc, char** argv) SrcNibbleBuffer[i+3] = 0xEF; } - buffer.SetLight(SrcNibbleBuffer); - NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; + buffer.SetBlockLight(SrcNibbleBuffer); + NIBBLETYPE DstNibbleBuffer[16 * 16 * 256 / 2]; + buffer.CopyBlockLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) - 1) == 0); - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - buffer.SetLight(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; + buffer.SetBlockLight(SrcNibbleBuffer); + buffer.CopyBlockLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) - 1) == 0); } { cChunkData buffer; - NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; + NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) { SrcNibbleBuffer[i+0] = 0xAD; @@ -126,68 +97,38 @@ int main(int argc, char** argv) } buffer.SetSkyLight(SrcNibbleBuffer); - NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + NIBBLETYPE DstNibbleBuffer[16 * 16 * 256/ 2]; buffer.CopySkyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); + memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 / 2); buffer.SetSkyLight(SrcNibbleBuffer); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; buffer.CopySkyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); } { cChunkData buffer; - BLOCKTYPE * SrcBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); - BLOCKTYPE * DstBlockBuffer = new BLOCKTYPE[16 * 16 * 256]; + BLOCKTYPE DstBlockBuffer[16 * 16 * 256]; buffer.CopyBlocks(DstBlockBuffer); - testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) -1) == 0); - delete SrcBlockBuffer; - delete DstBlockBuffer; - SrcBlockBuffer = NULL; - DstBlockBuffer = NULL; + testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) - 1) == 0); - NIBBLETYPE * SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - NIBBLETYPE * DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); + NIBBLETYPE DstNibbleBuffer[16 * 16 * 256 / 2]; buffer.CopyMeta(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; - buffer.CopyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; + memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); + buffer.CopyBlockLight(DstNibbleBuffer); + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); - SrcNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/2]; - memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); - DstNibbleBuffer = new NIBBLETYPE[16 * 16 * 256/ 2]; + memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 / 2); buffer.CopySkyLight(DstNibbleBuffer); - testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) -1) == 0); - delete SrcNibbleBuffer; - delete DstNibbleBuffer; - SrcNibbleBuffer = NULL; - DstNibbleBuffer = NULL; + testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); } } From 7fac63cffbe226ab025435a1e01e5f2430e52806 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 24 May 2014 13:37:25 +0100 Subject: [PATCH 104/312] Moved accessors to cpp file --- src/ChunkData.cpp | 230 +++++++++++++++++++++++++++++++++++++++++++++- src/ChunkData.h | 227 +++------------------------------------------ 2 files changed, 241 insertions(+), 216 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 098f436f8..162803292 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -2,7 +2,235 @@ #include "Globals.h" #include "ChunkData.h" -cChunkData cChunkData::Copy() const +cChunkData::cChunkData() +#if __cplusplus < 201103L + // auto_ptr style interface for memory management + : IsOwner(true) +#endif +{ + memset(m_Sections, 0, sizeof(m_Sections)); +} + + +cChunkData::~cChunkData() +{ + #if __cplusplus < 201103L + // auto_ptr style interface for memory management + if (!IsOwner) + { + return; + } + #endif + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + if (m_Sections[i] == NULL) Free(m_Sections[i]);; + } +} + +#if __cplusplus < 201103L + // auto_ptr style interface for memory management + cChunkData::cChunkData(const cChunkData& other) : + IsOwner(true) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + m_Sections[i] = other.m_Sections[i]; + } + other.IsOwner = false; + } + + cChunkData::cChunkData& operator=(const cChunkData& other) + { + if (&other != this) + { + if (IsOwner) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + if (m_Sections[i]) Free(m_Sections[i]);; + } + } + IsOwner = true; + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + m_Sections[i] = other.m_Sections[i]; + } + other.IsOwner = false; + } + return *this; + + } +#else + // unique_ptr style interface for memory management + cChunkData::cChunkData(cChunkData&& other) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + m_Sections[i] = other.m_Sections[i]; + other.m_Sections[i] = NULL; + } + } + + cChunkData::cChunkData& operator=(cChunkData&& other) + { + if (&other != this) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; 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 / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] != NULL) + { + int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * CHUNK_SECTION_HEIGHT), 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 / CHUNK_SECTION_HEIGHT; + 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 * CHUNK_SECTION_HEIGHT), 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 / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] != NULL) + { + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + return (m_Sections[Section]->m_BlockMeta[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 / CHUNK_SECTION_HEIGHT; + 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 * CHUNK_SECTION_HEIGHT), a_RelZ); + NIBBLETYPE oldval = m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4) & 0xf; + m_Sections[Section]->m_BlockMeta[Index / 2] = static_cast( + (m_Sections[Section]->m_BlockMeta[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 / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] != NULL) + { + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), 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 / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] != NULL) + { + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + } + else + { + return 0xF; + } + } + ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); + return 0; +} + +cChunkData cChunkData::cChunkData::Copy() const { cChunkData copy; for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) diff --git a/src/ChunkData.h b/src/ChunkData.h index 5a149f95f..16fcc4d37 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -20,231 +20,28 @@ class cChunkData { public: - cChunkData() - #if __cplusplus < 201103L - // auto_ptr style interface for memory management - : IsOwner(true) - #endif - { - memset(m_Sections, 0, sizeof(m_Sections)); - } - ~cChunkData() - { - #if __cplusplus < 201103L - // auto_ptr style interface for memory management - if (!IsOwner) - { - return; - } - #endif - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - if (m_Sections[i] == NULL) Free(m_Sections[i]);; - } - } + cChunkData(); + ~cChunkData(); #if __cplusplus < 201103L // auto_ptr style interface for memory management - cChunkData(const cChunkData& other) : - IsOwner(true) - { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - m_Sections[i] = other.m_Sections[i]; - } - other.IsOwner = false; - } - - cChunkData& operator=(const cChunkData& other) - { - if (&other != this) - { - if (IsOwner) - { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - if (m_Sections[i]) Free(m_Sections[i]);; - } - } - IsOwner = true; - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - m_Sections[i] = other.m_Sections[i]; - } - other.IsOwner = false; - } - return *this; - - } + cChunkData(const cChunkData& other); + cChunkData& operator=(const cChunkData& other); #else // unique_ptr style interface for memory management - cChunkData(cChunkData&& other) - { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = NULL; - } - } - - cChunkData& operator=(cChunkData&& other) - { - if (&other != this) - { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - Free(m_Sections[i]);; - m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = NULL; - } - } - return *this; - } + cChunkData(cChunkData&& other); + cChunkData& operator=(cChunkData&& other); #endif - BLOCKTYPE 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 / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] != NULL) - { - int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * CHUNK_SECTION_HEIGHT), a_Z); - return m_Sections[Section]->m_BlockTypes[Index]; - } - else - { - return 0; - } - } - - void 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; - } + 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); - int Section = a_RelY / CHUNK_SECTION_HEIGHT; - 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 * CHUNK_SECTION_HEIGHT), a_RelZ); - m_Sections[Section]->m_BlockTypes[Index] = a_Block; - } - - NIBBLETYPE 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 / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] != NULL) - { - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); - return (m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4)) & 0x0f; - } - else - { - return 0; - } - } - ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); - return 0; - } + 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); - bool 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 / CHUNK_SECTION_HEIGHT; - 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 * CHUNK_SECTION_HEIGHT), a_RelZ); - NIBBLETYPE oldval = m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4) & 0xf; - m_Sections[Section]->m_BlockMeta[Index / 2] = static_cast( - (m_Sections[Section]->m_BlockMeta[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble - ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set - ); - return oldval == a_Nibble; - } + NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const; - NIBBLETYPE 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 / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] != NULL) - { - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), 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 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 / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] != NULL) - { - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); - return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; - } - else - { - return 0xF; - } - } - ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); - return 0; - } + NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; cChunkData Copy() const; void CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx = 0, size_t length = cChunkDef::NumBlocks) const; From 96a22cd82c350b1205985a9b8e01f5e6c11f069a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 24 May 2014 15:03:39 +0200 Subject: [PATCH 105/312] Added Japanese village prefabs. --- src/Generating/Prefab.cpp | 9 + src/Generating/Prefab.h | 3 + .../Prefabs/JapaneseVillagePrefabs.cpp | 2404 +++++++++++++++++ .../Prefabs/JapaneseVillagePrefabs.h | 15 + src/Generating/VillageGen.cpp | 15 +- 5 files changed, 2442 insertions(+), 4 deletions(-) create mode 100644 src/Generating/Prefabs/JapaneseVillagePrefabs.cpp create mode 100644 src/Generating/Prefabs/JapaneseVillagePrefabs.h diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 506e1c2cc..05979507a 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -292,6 +292,15 @@ 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)); diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index 2b89a204c..adc0e688e 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -104,6 +104,9 @@ public: 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; } diff --git a/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp b/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp new file mode 100644 index 000000000..2b129f520 --- /dev/null +++ b/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp @@ -0,0 +1,2404 @@ + +// 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, + }, // 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, + }, // Forge + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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, + }, // 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, + }, // HouseSmall + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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, + }, // HouseSmallDouble + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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, + }, // 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, + }, // 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, + }, // HouseWithSakura1 + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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, + }, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 11, 7, 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* 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: 0, 2, 2: 4\n" /* Type -1, direction X- */, + + // AllowedRotations: + 7, /* 1, 2, 3 CCW rotation allowed */ + + // Merge strategy: + cBlockArea::msSpongePrint, + + // ShouldExtendFloor: + true, + + // DefaultWeight: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + }, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 4, 6, 4, // 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, 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, + }, // 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, + }, // 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, + }, // 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/VillageGen.cpp b/src/Generating/VillageGen.cpp index bcce62af5..62822c33b 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "VillageGen.h" +#include "Prefabs/JapaneseVillagePrefabs.h" #include "Prefabs/PlainsVillagePrefabs.h" #include "Prefabs/SandVillagePrefabs.h" #include "Prefabs/SandFlatRoofVillagePrefabs.h" @@ -59,6 +60,7 @@ public: 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) @@ -84,8 +86,8 @@ public: // 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): - if ((a_ExistingConnector.m_Type == 2) && (a_PlacedPiece.GetDepth() > 0)) + // 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; } @@ -283,6 +285,9 @@ static cVillagePiecePool g_SandFlatRoofVillage(g_SandFlatRoofVillagePrefabs, g_S /** The prefabs for the plains village. */ static cVillagePiecePool g_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVillagePrefabsCount, g_PlainsVillageStartingPrefabs, g_PlainsVillageStartingPrefabsCount); +/** The prefabs for the Japanese village. */ +static cVillagePiecePool g_JapaneseVillage(g_JapaneseVillagePrefabs, g_JapaneseVillagePrefabsCount, g_JapaneseVillageStartingPrefabs, g_JapaneseVillageStartingPrefabsCount); + @@ -316,6 +321,8 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ cVillagePiecePool * VillagePrefabs = NULL; BLOCKTYPE RoadBlock = E_BLOCK_GRAVEL; int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 11; + cVillagePiecePool * PlainsVillage = (rnd % 2 == 0) ? &g_PlainsVillage : &g_JapaneseVillage; + cVillagePiecePool * DesertVillage = (rnd % 2 == 0) ? &g_SandVillage : &g_SandFlatRoofVillage; for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++) { switch (Biomes[i]) @@ -324,7 +331,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ case biDesertM: { // These biomes allow sand villages - VillagePrefabs = (rnd % 2 == 0) ? &g_SandVillage : &g_SandFlatRoofVillage; + VillagePrefabs = DesertVillage; // RoadBlock = E_BLOCK_SANDSTONE; break; } @@ -334,7 +341,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ case biSunflowerPlains: { // These biomes allow plains-style villages - VillagePrefabs = &g_PlainsVillage; + VillagePrefabs = PlainsVillage; break; } default: From 944d29c0ae3929471a11ea11aa98441bc31f4d7d Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 24 May 2014 14:09:51 +0100 Subject: [PATCH 106/312] inject TestGlobals.h correctly --- src/ChunkData.cpp | 10 +++++++--- tests/ChunkData/CMakeLists.txt | 1 + tests/TestGlobals.h | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 162803292..79029f0cf 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -1,5 +1,9 @@ +#ifdef TEST_GLOBALS +#include "TestGlobals.h" +#else #include "Globals.h" +#endif #include "ChunkData.h" cChunkData::cChunkData() @@ -39,7 +43,7 @@ cChunkData::~cChunkData() other.IsOwner = false; } - cChunkData::cChunkData& operator=(const cChunkData& other) + cChunkData& cChunkData::operator=(const cChunkData& other) { if (&other != this) { @@ -71,7 +75,7 @@ cChunkData::~cChunkData() } } - cChunkData::cChunkData& operator=(cChunkData&& other) + cChunkData& cChunkData::operator=(cChunkData&& other) { if (&other != this) { @@ -230,7 +234,7 @@ NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const return 0; } -cChunkData cChunkData::cChunkData::Copy() const +cChunkData cChunkData::Copy() const { cChunkData copy; for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) diff --git a/tests/ChunkData/CMakeLists.txt b/tests/ChunkData/CMakeLists.txt index 3f6653bb5..a2bd9fd22 100644 --- a/tests/ChunkData/CMakeLists.txt +++ b/tests/ChunkData/CMakeLists.txt @@ -4,6 +4,7 @@ enable_testing() include_directories(${CMAKE_SOURCE_DIR}/src/) +add_definitions(-DTEST_GLOBALS=1) add_library(ChunkBuffer ${CMAKE_SOURCE_DIR}/src/ChunkData.cpp) diff --git a/tests/TestGlobals.h b/tests/TestGlobals.h index bb25bd20a..ea43de733 100644 --- a/tests/TestGlobals.h +++ b/tests/TestGlobals.h @@ -126,9 +126,9 @@ class cAssertFailure #define UNUSED(X) (void)(X) // Logging functions -void LOGERROR(const char* a_Format, ...) FORMATSTRING(1,2); +void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1,2); -void LOGERROR(const char* a_Format, ...) +void inline LOGERROR(const char* a_Format, ...) { va_list argList; va_start(argList, a_Format); From f3a8560f89492be4f221dcea9afcb9942ff92935 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 21:48:12 +0100 Subject: [PATCH 107/312] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a16062574..07517751c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -MCServer +MCServer [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) ======== **Current Protocol Supported:** Minecraft v1.2 -> v1.7 @@ -34,5 +34,7 @@ For other stuff, including plugins and discussion, check the [forums](http://for Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) +[![Support via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png)](https://www.gittip.com/USERNAME/) + Travis CI: [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) From bc4d7b3d35a66466fc82174dacbdb3d19eab217a Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 21:48:38 +0100 Subject: [PATCH 108/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 07517751c..9b39f7d1d 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ For other stuff, including plugins and discussion, check the [forums](http://for Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) -[![Support via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png)](https://www.gittip.com/USERNAME/) +[![Support via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png)](https://www.gittip.com/on/github/mc-server/) Travis CI: [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) From 86086aa3573f606924aae77fcc2c07249a7ad899 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 21:49:45 +0100 Subject: [PATCH 109/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9b39f7d1d..8a3de6465 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ For other stuff, including plugins and discussion, check the [forums](http://for Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) -[![Support via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png)](https://www.gittip.com/on/github/mc-server/) +[![Support via Gittip](http://img.shields.io/gittip/mc-server.svg)](https://www.gittip.com/on/github/mc-server/) Travis CI: [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) From 078b5f6506a1265d9c970882622692037d8698d0 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 21:55:02 +0100 Subject: [PATCH 110/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a3de6465..61ffdaa5f 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ For other stuff, including plugins and discussion, check the [forums](http://for Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) -[![Support via Gittip](http://img.shields.io/gittip/mc-server.svg)](https://www.gittip.com/on/github/mc-server/) +[![Support via Gittip](http://img.shields.io/gittip/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) Travis CI: [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) From bd68b71dd7c4357e448abefe20d7dc08ad8dc370 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 21:55:55 +0100 Subject: [PATCH 111/312] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 61ffdaa5f..0b1038be0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -MCServer [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) +MCServer [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) [![Support via Gittip](http://img.shields.io/gittip/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) ======== **Current Protocol Supported:** Minecraft v1.2 -> v1.7 @@ -34,7 +34,7 @@ For other stuff, including plugins and discussion, check the [forums](http://for Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) -[![Support via Gittip](http://img.shields.io/gittip/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) +Support Via Gittip: [![Support via Gittip](http://img.shields.io/gittip/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) Travis CI: [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) From 0d7dd5fe7679669046129892de5d9e9abec2320a Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 21:56:56 +0100 Subject: [PATCH 112/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0b1038be0..752c55325 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -MCServer [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) [![Support via Gittip](http://img.shields.io/gittip/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) +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/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) ======== **Current Protocol Supported:** Minecraft v1.2 -> v1.7 From deb69f150d3cdd0abc97905868370dad48cce468 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 22:00:16 +0100 Subject: [PATCH 113/312] Standardised a badge. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 752c55325..b867c399c 100644 --- a/README.md +++ b/README.md @@ -36,5 +36,5 @@ Earn bitcoins for commits or donate to reward the MCServer developers: [![tip fo Support Via Gittip: [![Support via Gittip](http://img.shields.io/gittip/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) -Travis CI: [![Build Status](https://travis-ci.org/mc-server/MCServer.png?branch=master)](https://travis-ci.org/mc-server/MCServer) +Travis CI: [![Build Status]((http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer) From ecb358a36e193316b7a00857ae0b7e9ae2707665 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 22:02:19 +0100 Subject: [PATCH 114/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b867c399c..5748e4083 100644 --- a/README.md +++ b/README.md @@ -36,5 +36,5 @@ Earn bitcoins for commits or donate to reward the MCServer developers: [![tip fo Support Via Gittip: [![Support via Gittip](http://img.shields.io/gittip/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) -Travis CI: [![Build Status]((http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer) +Travis CI: [![Build Status]((http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer)) From cc2b84ed9e5ab106bc016df57c0dfca863318ec4 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 22:03:31 +0100 Subject: [PATCH 115/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5748e4083..5f82c2b11 100644 --- a/README.md +++ b/README.md @@ -36,5 +36,5 @@ Earn bitcoins for commits or donate to reward the MCServer developers: [![tip fo Support Via Gittip: [![Support via Gittip](http://img.shields.io/gittip/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) -Travis CI: [![Build Status]((http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer)) +Travis CI: [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer) From 2eca98a41a03c1f0478f93028f0c7c232689b6f4 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 24 May 2014 22:04:15 +0100 Subject: [PATCH 116/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f82c2b11..e7c0730bc 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/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) +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/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) ======== **Current Protocol Supported:** Minecraft v1.2 -> v1.7 From 27a9fa31108aef4313a45f4c716f2f1551537236 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 24 May 2014 23:28:48 +0100 Subject: [PATCH 117/312] Updated Core --- MCServer/Plugins/Core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/Core b/MCServer/Plugins/Core index 5c8557d4f..3790f78d3 160000 --- a/MCServer/Plugins/Core +++ b/MCServer/Plugins/Core @@ -1 +1 @@ -Subproject commit 5c8557d4fdfa580c100510cde07a1a778ea2e244 +Subproject commit 3790f78d3f7503ff33a423b8e73e81a275562783 From 43eaa573fd09a0cbf2f8f6333bb3217717f8438b Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 25 May 2014 10:03:53 +0100 Subject: [PATCH 118/312] Updated the installation instructions in the README. --- README.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e7c0730bc..22871efe4 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,23 @@ 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/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) ======== -**Current Protocol Supported:** Minecraft v1.2 -> v1.7 - MCServer is a performant C++ Minecraft server designed for use in memory and cpu-limited places, or just to make regular server perform better. MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis. +**MCServer Currently Supports:** Minecraft v1.2 -> v1.7 + Installation ------------ -To install MCServer, you can either download the repository and compile it, or download a pre-compiled version. +Normally, you will want to download a pre-compiled version of MCServer from one of the buildservers: -If you've cloned the repository using Git, you need to pull down the submodules (core plugins, some dependencies). This can be achieved with `git submodule init` and then on a regular basis (to keep up to date) `git submodule update`. + * [Linux and Raspberry Pi](http://ci.bearbin.net) (Bearbin's CI Server) + * [Windows](http://mc-server.xoft.cz) (xoft's nightly build service) -If you downloaded a ZIP file of the sources instead, you will need to download PolarSSL, too, from https://github.com/polarssl/polarssl , and unpack it into the `lib/polarssl` folder. You will also need to manually download all the plugins that you want included. +You simply need to download and extract these files before you can use the server. -Compilation instructions are available in the COMPILING file. - -Linux builds can be downloaded from [Bearbin's CI Service](http://ci.bearbin.net) and Windows builds from xoft's [nightly build service](http://mc-server.xoft.cz). - -After you've extracted the files, simply run the MCServer executable. +If you're a more advanced user, you may want to compile the server yourself for more performance. See the [COMPILING.md](https://github.com/mc-server/MCServer/blob/master/COMPILING.md) file for more details. Contributing ------------ @@ -30,7 +27,7 @@ MCServer is licensed under the Apache license V2, and we welcome anybody to fork Other Stuff ----------- -For other stuff, including plugins and discussion, check the [forums](http://forum.mc-server.org) and [wiki](http://wiki.mc-server.org/). +For other stuff, including plugins and discussion, check the [forums](http://forum.mc-server.org) and [Plugin API](http://mc-server.xoft.cz/LuaAPI/). Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) From bcdced34ab6be6767c121ac4cfef0fce7f9bc5bf Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 25 May 2014 10:06:41 +0100 Subject: [PATCH 119/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22871efe4..c9a8f5eff 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ MCServer is a performant C++ Minecraft server designed for use in memory and cpu MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis. -**MCServer Currently Supports:** Minecraft v1.2 -> v1.7 +We currently support the protocol from Minecraft 1.2 all the way up to Minecraft 1.7.9. Installation ------------ From 34d69bd5899d0e54574bddf16215fa23bcaa9832 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 25 May 2014 10:08:26 +0100 Subject: [PATCH 120/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9a8f5eff..a4a8b3273 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ 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/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) ======== -MCServer is a performant C++ Minecraft server designed for use in memory and cpu-limited places, or just to make regular server perform better. +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. MCServer can run on PCs, Macs, and *nix. This includes android phones and tablets as well as Raspberry Pis. From 882e8e044c56878cd144b93ea67182204581489c Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 25 May 2014 10:21:58 +0100 Subject: [PATCH 121/312] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a4a8b3273..22befc822 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ Contributing MCServer is licensed under the Apache license V2, and we welcome anybody to fork and submit a Pull Request back with their changes, and if you want to join as a permanent member we can add you to the team. +Check out the [CONTRIBUTING.md](https://github.com/mc-server/MCServer/blob/master/CONTRIBUTING.md) file for more infos. + Other Stuff ----------- From ee929793f09c431693e1bef7edd77213ba412f60 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 25 May 2014 13:46:34 +0100 Subject: [PATCH 122/312] Hopefully fixed piston duplication issues * Fixes #879 * Fixes #714 --- src/Blocks/BlockDropSpenser.h | 4 +- src/Blocks/BlockFurnace.h | 4 +- src/Blocks/BlockMobHead.h | 2 +- src/Blocks/BlockPiston.cpp | 166 +++++++++- src/Blocks/BlockPiston.h | 129 +++++++- src/Chunk.cpp | 11 +- src/Chunk.h | 4 +- src/ChunkMap.cpp | 4 +- src/ChunkMap.h | 2 +- src/ClientHandle.cpp | 1 - src/Piston.cpp | 297 ------------------ src/Piston.h | 110 ------- .../IncrementalRedstoneSimulator.cpp | 9 +- src/World.cpp | 48 ++- src/World.h | 18 +- 15 files changed, 372 insertions(+), 437 deletions(-) delete mode 100644 src/Piston.cpp delete mode 100644 src/Piston.h 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/BlockMobHead.h b/src/Blocks/BlockMobHead.h index b7629b07c..9855574ad 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -68,7 +68,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_World->DoWithMobHeadAt(a_BlockX, a_BlockY, a_BlockZ, CallbackA); diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 542eb33b5..f758013dc 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,15 @@ 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 + @@ -40,7 +47,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 +67,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 +75,155 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( +int cBlockPistonHandler::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, NIBBLETYPE pistonmeta, cWorld * a_World) +{ + // Examine each of the 12 blocks ahead of the piston: + for (int ret = 0; ret < 12; ret++) + { + BLOCKTYPE currBlock; + NIBBLETYPE currMeta; + AddPistonDir(pistonX, pistonY, pistonZ, pistonmeta, 1); + a_World->GetBlockTypeMeta(pistonX, pistonY, 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; + 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); + a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(oldx, oldy, oldz)); + oldx = a_BlockX; + oldy = a_BlockY; + oldz = a_BlockZ; + } + + int extx = a_BlockX; + int exty = a_BlockY; + int extz = a_BlockZ; + 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(extx, exty, extz)); +} + + + + + +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); + a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(a_BlockX, a_BlockY, a_BlockZ)); + a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(tempx, tempy, tempz)); + return; + } + } + + // Retract without pulling + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0, false); + a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(a_BlockX, a_BlockY, a_BlockZ)); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cBlockPistonHeadHandler: @@ -87,7 +243,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..d7c92925b 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -21,6 +21,133 @@ 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; + } + } + + return CanBreakPush(a_BlockType) ? false /* CanBreakPush returns true, but we need false to prevent pulling */ : 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 +167,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/Chunk.cpp b/src/Chunk.cpp index ca536e89a..6bd68459c 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1462,9 +1462,9 @@ 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); + FastSetBlock(a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta, a_SendToClients); const int index = MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); @@ -1565,7 +1565,7 @@ 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))); @@ -1589,13 +1589,14 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT // The client doesn't need to distinguish between stationary and nonstationary fluids: if ( - (OldBlockMeta != a_BlockMeta) || // Different meta always gets sent to the client + a_SendToClients && + ((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 - ) + )) ) { m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta)); diff --git a/src/Chunk.h b/src/Chunk.h index 84ec35496..8eeb183e3 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -139,7 +139,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,7 +152,7 @@ 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; void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index d7164a6a5..3c87403ff 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1255,7 +1255,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 +1270,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); diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 9d973f2a9..a64942112 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -152,7 +152,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); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 83b21ae3c..433b7edf7 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" 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/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 074063add..c24b1c4b3 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -11,7 +11,7 @@ #include "../Blocks/BlockDoor.h" #include "../Blocks/BlockButton.h" #include "../Blocks/BlockLever.h" -#include "../Piston.h" +#include "../Blocks/BlockPiston.h" @@ -814,17 +814,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); } } @@ -1491,7 +1490,7 @@ 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); + eBlockFace Face = cBlockPistonHandler::MetaDataToDirection(a_Meta); int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; diff --git a/src/World.cpp b/src/World.cpp index 807065bfa..29046bba9 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1551,9 +1551,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); } @@ -3127,6 +3127,50 @@ void cWorld::cTaskUnloadUnusedChunks::Run(cWorld & a_World) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cWorld::cTaskSendBlockTo + +cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(int a_BlockX, int a_BlockY, int a_BlockZ) : + m_BlockX(a_BlockX), + m_BlockY(a_BlockY), + m_BlockZ(a_BlockZ) +{ +} + +void cWorld::cTaskSendBlockToAllPlayers::Run(cWorld & a_World) +{ + class cPlayerCallback : + public cPlayerListCallback + { + public: + cPlayerCallback(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld & a_World) : + m_BlockX(a_BlockX), + m_BlockY(a_BlockY), + m_BlockZ(a_BlockZ), + m_World(a_World) + { + } + + virtual bool Item(cPlayer * a_Player) + { + m_World.SendBlockTo(m_BlockX, m_BlockY, m_BlockZ, a_Player); + return false; + } + + private: + + int m_BlockX, m_BlockY, m_BlockZ; + cWorld & m_World; + + } PlayerCallback(m_BlockX, m_BlockY, m_BlockZ, a_World); + + a_World.ForEachPlayer(PlayerCallback); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cWorld::cChunkGeneratorCallbacks: diff --git a/src/World.h b/src/World.h index 86cbb3e7e..5ef63a540 100644 --- a/src/World.h +++ b/src/World.h @@ -117,6 +117,22 @@ public: }; + class cTaskSendBlockToAllPlayers : + public cTask + { + public: + cTaskSendBlockToAllPlayers(int a_BlockX, int a_BlockY, int a_BlockZ); + + protected: + // cTask overrides: + virtual void Run(cWorld & a_World) override; + + int m_BlockX; + int m_BlockY; + int m_BlockZ; + }; + + static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates { return "cWorld"; @@ -373,7 +389,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. From 67308e4337b422ebefb249049e662266072b0ba2 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 25 May 2014 13:46:50 +0100 Subject: [PATCH 123/312] Fixed a food saturation issue --- src/Entities/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 0eacb67f9..1e1e868e7 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -551,7 +551,7 @@ bool cPlayer::Feed(int a_Food, double a_Saturation) } m_FoodLevel = std::min(a_Food + m_FoodLevel, (int)MAX_FOOD_LEVEL); - m_FoodSaturationLevel = std::min(m_FoodSaturationLevel + a_Saturation, (double)m_FoodLevel); + m_FoodSaturationLevel = m_FoodSaturationLevel + a_Saturation; SendHealth(); return true; From 50e29aba776dd6ad6296e5989faaf4642b4b6705 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 25 May 2014 18:32:42 +0100 Subject: [PATCH 124/312] A fix that is better than #950. --- src/GroupManager.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index 3586560bf..ba25d95ba 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -45,8 +45,14 @@ cGroupManager::cGroupManager() { LOGD("-- Loading Groups --"); - LoadGroups(); - CheckUsers(); + if (!LoadGroups()) + { + LOGWARNING("ERROR: Groups could not load!"); + } + if (!CheckUsers()) + { + LOGWARNING("ERROR: User file could not be found!"); + } LOGD("-- Groups Successfully Loaded --"); } @@ -70,13 +76,13 @@ void cGroupManager::GenerateDefaultUsersIni(cIniFile & a_IniFile) -void cGroupManager::CheckUsers(void) +bool cGroupManager::CheckUsers() { cIniFile IniFile; if (!IniFile.ReadFile("users.ini")) { GenerateDefaultUsersIni(IniFile); - return; + return true; } int NumKeys = IniFile.GetNumKeys(); @@ -97,13 +103,15 @@ void cGroupManager::CheckUsers(void) } } // for itr - Split[] } // for i - ini file keys + // Always return true for now, just but we can handle writefile fails later. + return true } -void cGroupManager::LoadGroups() +bool cGroupManager::LoadGroups() { cIniFile IniFile; if (!IniFile.ReadFile("groups.ini")) @@ -180,6 +188,8 @@ void cGroupManager::LoadGroups() } } } + // Always return true, we can handle writefile fails later. + return true } From 6ce73ada6fc1cde9cd3ee25afdca11484e77cbb0 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 25 May 2014 19:17:01 +0100 Subject: [PATCH 125/312] Update GroupManager.h --- src/GroupManager.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GroupManager.h b/src/GroupManager.h index 9e1689a76..d42b55c4a 100644 --- a/src/GroupManager.h +++ b/src/GroupManager.h @@ -16,8 +16,8 @@ class cGroupManager public: bool ExistsGroup(const AString & a_Name); cGroup * GetGroup(const AString & a_Name); - void LoadGroups(void); - void CheckUsers(void); + bool LoadGroups(); + bool CheckUsers(); /** Writes the default header to the specified ini file, and saves it as "users.ini". */ static void GenerateDefaultUsersIni(cIniFile & a_IniFile); From a352ec38958f2884d6fe12fa7320947c65d1a65f Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 25 May 2014 19:46:16 +0100 Subject: [PATCH 126/312] SEMICOLONS! --- src/GroupManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GroupManager.cpp b/src/GroupManager.cpp index ba25d95ba..523697b07 100644 --- a/src/GroupManager.cpp +++ b/src/GroupManager.cpp @@ -104,7 +104,7 @@ bool cGroupManager::CheckUsers() } // for itr - Split[] } // for i - ini file keys // Always return true for now, just but we can handle writefile fails later. - return true + return true; } @@ -189,7 +189,7 @@ bool cGroupManager::LoadGroups() } } // Always return true, we can handle writefile fails later. - return true + return true; } From 1a742a2b52d32bd22cd57b4d462bee312717e010 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 25 May 2014 23:50:16 +0200 Subject: [PATCH 127/312] Added support for Miners' Village. The village contains both prefabs that snap to ground and prefabs that connect strictly via connectors. Fixes #1027. --- src/Generating/PieceGenerator.cpp | 13 +- src/Generating/PieceGenerator.h | 21 +- src/Generating/Prefab.cpp | 6 +- src/Generating/Prefab.h | 12 + .../Prefabs/JapaneseVillagePrefabs.cpp | 808 ++- src/Generating/Prefabs/NetherFortPrefabs.cpp | 102 + .../Prefabs/PlainsVillagePrefabs.cpp | 5093 ++++++++++------- .../Prefabs/SandFlatRoofVillagePrefabs.cpp | 115 +- src/Generating/Prefabs/SandVillagePrefabs.cpp | 545 +- src/Generating/VillageGen.cpp | 45 +- 10 files changed, 4482 insertions(+), 2278 deletions(-) diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index 7d478f1a1..1880a20d5 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); @@ -317,6 +318,16 @@ cPiece::cConnector cPlacedPiece::GetRotatedConnector(const cPiece::cConnector & +void cPlacedPiece::MoveToGroundBy(int a_OffsetY) +{ + m_Coords.y += a_OffsetY; + m_HasBeenMovedToGround = true; +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPieceGenerator: diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index e396643a9..21c155c96 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -139,11 +139,13 @@ 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; } @@ -156,6 +158,11 @@ public: 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; @@ -163,6 +170,10 @@ protected: int m_NumCCWRotations; 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 cPlacedPieces; diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index 05979507a..e41907325 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -127,7 +127,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; @@ -149,7 +150,8 @@ cPrefab::cPrefab(const cBlockArea & a_Image, int a_AllowedRotations) : m_MergeStrategy(cBlockArea::msOverwrite), m_ShouldExtendFloor(false), m_DefaultWeight(1), - m_AddWeightIfSame(0) + 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); diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index adc0e688e..8b4e4b4ef 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -82,6 +82,10 @@ 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; }; @@ -115,6 +119,10 @@ public: /** 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. */ @@ -169,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: diff --git a/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp b/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp index 2b129f520..5ec222f84 100644 --- a/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp +++ b/src/Generating/Prefabs/JapaneseVillagePrefabs.cpp @@ -122,6 +122,9 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // Arch @@ -385,10 +388,165 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // 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 @@ -558,6 +716,9 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // HouseMid @@ -666,10 +827,137 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // 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 @@ -784,10 +1072,126 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // 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 @@ -929,6 +1333,9 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // HouseWide @@ -1172,6 +1579,9 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // HouseWithGarden @@ -1363,10 +1773,375 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // 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 @@ -1614,6 +2389,9 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // Restaurant @@ -1626,8 +2404,8 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = 12, 8, 6, // SizeX = 12, SizeY = 8, SizeZ = 6 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 11, 7, 5, // MaxX, MaxY, MaxZ + -1, 0, -1, // MinX, MinY, MinZ + 12, 7, 6, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1719,7 +2497,11 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = /* 5 */ "............", // Connectors: - "-1: 0, 2, 2: 4\n" /* Type -1, direction X- */, + "-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 */ @@ -1738,6 +2520,9 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // SakuraDouble @@ -1750,8 +2535,8 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = 5, 7, 5, // SizeX = 5, SizeY = 7, SizeZ = 5 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 4, 6, 4, // MaxX, MaxY, MaxZ + -1, 0, -1, // MinX, MinY, MinZ + 5, 6, 5, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1819,7 +2604,9 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = /* 4 */ ".....", // Connectors: - "-1: 2, 2, 0: 2\n" /* Type -1, direction Z- */, + "-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 */ @@ -1838,6 +2625,9 @@ const cPrefab::sDef g_JapaneseVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // SakuraSmall }; // g_JapaneseVillagePrefabs @@ -2192,6 +2982,9 @@ const cPrefab::sDef g_JapaneseVillageStartingPrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // HighTemple @@ -2389,6 +3182,9 @@ const cPrefab::sDef g_JapaneseVillageStartingPrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // Well }; 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 index 28488be14..fee6610c9 100644 --- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -20,11 +20,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 26, ID 70, created by Taugrammaton { // Size: - 13, 4, 12, // SizeX = 13, SizeY = 4, SizeZ = 12 + 13, 8, 12, // SizeX = 13, SizeY = 8, SizeZ = 12 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 12, 3, 11, // MaxX, MaxY, MaxZ + 12, 7, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -36,6 +36,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "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: @@ -101,7 +102,71 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 8 */ "ghh..h....hhg" /* 9 */ "ghh.....h.hhg" /* 10 */ "ghh.hh.h..hhg" - /* 11 */ "g..g..g..g..g", + /* 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+ */, @@ -123,6 +188,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // BigPlantBed @@ -132,130 +200,117 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 23, ID 66, created by xoft { // Size: - 12, 8, 7, // SizeX = 12, SizeY = 8, SizeZ = 7 + 12, 7, 7, // SizeX = 12, SizeY = 7, SizeZ = 7 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 12, 7, 7, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 12, 6, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 64: 7\n" /* wooddoorblock */ - "h: 53: 3\n" /* woodstairs */ - "i: 53: 1\n" /* woodstairs */ - "j: 85: 0\n" /* fence */ - "k: 53: 0\n" /* woodstairs */ - "l: 53: 2\n" /* woodstairs */ + "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:102: 0\n" /* glasspane */ - "o: 64:12\n" /* wooddoorblock */ - "p: 50: 3\n" /* torch */ - "q: 72: 0\n" /* woodplate */ - "r: 50: 4\n" /* torch */ - "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 */ - "x: 5: 0\n" /* wood */, + "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 */ "aaaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaaa" + /* 0 */ "mmmmmmmaaamm" + /* 1 */ "maaaaaaaaaam" + /* 2 */ "maaaaaaaaaam" + /* 3 */ "maaaaaaaaaam" + /* 4 */ "maaaaaaaaaam" + /* 5 */ "maaaaaaaaaam" + /* 6 */ "mmmmmmmmmmmm" // Level 1 /* z\x* 11 */ /* * 012345678901 */ - /* 0 */ "bbbbbbbaaabb" - /* 1 */ "baaaaaaaaaab" - /* 2 */ "baaaaaaaaaab" - /* 3 */ "baaaaaaaaaab" - /* 4 */ "baaaaaaaaaab" - /* 5 */ "baaaaaaaaaab" - /* 6 */ "bbbbbbbbbbbb" + /* 0 */ ".......bcd.." + /* 1 */ ".aaaaaaaaaa." + /* 2 */ ".aaaaaaaaaa." + /* 3 */ ".aaaaaaaaaa." + /* 4 */ ".aaaaaaaaaa." + /* 5 */ ".aaaaaaaaaa." + /* 6 */ "............" // Level 2 /* z\x* 11 */ /* * 012345678901 */ - /* 0 */ ".......cde.." - /* 1 */ ".ffffffffff." - /* 2 */ ".ffffffffff." - /* 3 */ ".ffffffffff." - /* 4 */ ".ffffffffff." - /* 5 */ ".ffffffffff." + /* 0 */ "............" + /* 1 */ ".aaaaaaaeaa." + /* 2 */ ".af.ghi...a." + /* 3 */ ".ah.......a." + /* 4 */ ".aj.ghighia." + /* 5 */ ".aaaaaaaaaa." /* 6 */ "............" // Level 3 /* z\x* 11 */ /* * 012345678901 */ /* 0 */ "............" - /* 1 */ ".fffffffgff." - /* 2 */ ".fh.ijk...f." - /* 3 */ ".fj.......f." - /* 4 */ ".fl.ijkijkf." - /* 5 */ ".ffffffffff." + /* 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 */ "............" - /* 1 */ ".fnnfnnfoff." - /* 2 */ ".n..pq.p.pn." - /* 3 */ ".nq.......n." - /* 4 */ ".n..rq.rq.n." - /* 5 */ ".fnnfnnfnnf." - /* 6 */ "............" + /* 0 */ "jjjjjjjjjjjj" + /* 1 */ "qaaaaaaaaaaq" + /* 2 */ ".arrrrrrrra." + /* 3 */ ".as......ta." + /* 4 */ ".arrrrrrrra." + /* 5 */ "uaaaaaaaaaau" + /* 6 */ "ffffffffffff" // Level 5 /* z\x* 11 */ /* * 012345678901 */ - /* 0 */ "llllllllllll" - /* 1 */ "sffffffffffs" - /* 2 */ ".fttttttttf." - /* 3 */ ".fu......vf." - /* 4 */ ".fttttttttf." - /* 5 */ "wffffffffffw" - /* 6 */ "hhhhhhhhhhhh" + /* 0 */ "............" + /* 1 */ "jjjjjjjjjjjj" + /* 2 */ "qvvvvvvvvvvq" + /* 3 */ ".vvvvvvvvvv." + /* 4 */ "uvvvvvvvvvvu" + /* 5 */ "ffffffffffff" + /* 6 */ "............" // Level 6 /* z\x* 11 */ /* * 012345678901 */ /* 0 */ "............" - /* 1 */ "llllllllllll" - /* 2 */ "sxxxxxxxxxxs" - /* 3 */ ".xxxxxxxxxx." - /* 4 */ "wxxxxxxxxxxw" - /* 5 */ "hhhhhhhhhhhh" - /* 6 */ "............" - - // Level 7 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" /* 1 */ "............" - /* 2 */ "llllllllllll" - /* 3 */ "xxxxxxxxxxxx" - /* 4 */ "hhhhhhhhhhhh" + /* 2 */ "jjjjjjjjjjjj" + /* 3 */ "vvvvvvvvvvvv" + /* 4 */ "ffffffffffff" /* 5 */ "............" /* 6 */ "............", // Connectors: - "-1: 8, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 8, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -274,6 +329,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // CobbleHouse10x5Library @@ -283,50 +341,130 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 5, ID 20, created by tonibm1999 { // Size: - 15, 2, 9, // SizeX = 15, SizeY = 2, SizeZ = 9 + 15, 8, 9, // SizeX = 15, SizeY = 8, SizeZ = 9 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 14, 1, 8, // MaxX, MaxY, MaxZ + 14, 7, 8, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 17: 0\n" /* tree */ - "b: 60: 7\n" /* tilleddirt */ - "c: 8: 0\n" /* water */ - "d: 50: 5\n" /* torch */ - "e: 59: 7\n" /* crops */ + "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 */ "aaaaaaa.aaaaaaa" - /* 1 */ "abbcbba.abbcbba" - /* 2 */ "abbcbba.abbcbba" - /* 3 */ "abbcbba.abbcbba" - /* 4 */ "abbcbba.abbcbba" - /* 5 */ "abbcbba.abbcbba" - /* 6 */ "abbcbba.abbcbba" - /* 7 */ "abbcbba.abbcbba" - /* 8 */ "aaaaaaa.aaaaaaa" + /* 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 */ "d.....d.d.....d" - /* 1 */ ".ee.ee...ee.ee." - /* 2 */ ".e...e...ee.ee." - /* 3 */ ".e.......ee.ee." - /* 4 */ ".ee..e...ee.ee." - /* 5 */ ".ee..e...ee.ee." - /* 6 */ "..e..e...ee.ee." - /* 7 */ "..e.e....ee.ee." - /* 8 */ "d.....d.d.....d", + /* 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, 0, 8: 3\n" /* Type -1, direction Z+ */, + "-1: 7, 2, 8: 3\n" /* Type -1, direction Z+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -345,6 +483,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // DoublePlantBed @@ -354,160 +495,158 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 51, ID 102, created by Aloe_vera { // Size: - 12, 10, 11, // SizeX = 12, SizeY = 10, SizeZ = 11 + 12, 9, 11, // SizeX = 12, SizeY = 9, SizeZ = 11 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 12, 9, 11, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 12, 8, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 6\n" /* wooddoorblock */ - "j: 10: 0\n" /* lava */ - "k: 54: 2\n" /* chest */ - "l: 61: 2\n" /* furnace */ + "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:102: 0\n" /* glasspane */ - "o: 64:12\n" /* wooddoorblock */ - "p:139: 0\n" /* cobblestonewall */ - "q:101: 0\n" /* ironbars */ - "r: 53: 2\n" /* woodstairs */ - "s: 53: 7\n" /* woodstairs */ - "t: 50: 2\n" /* torch */ - "u: 50: 1\n" /* torch */ - "v: 53: 6\n" /* woodstairs */ - "w: 53: 3\n" /* woodstairs */ - "x: 43: 0\n" /* doubleslab */ - "y: 44: 0\n" /* step */, + "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 */ "aaaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaaa" - /* 7 */ "aaaaaaaaaaaa" - /* 8 */ "aaaaaaaaaaaa" - /* 9 */ "aaaaaaaaaaaa" - /* 10 */ "aaaaaaaaaaaa" + /* 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 */ "bbbbbaaaaabb" - /* 1 */ "baaaaaaaaabb" - /* 2 */ "baaaaaaaaabb" - /* 3 */ "baaaaaaaaaaa" - /* 4 */ "baaaaaaaaaaa" - /* 5 */ "baaaaaaaaaaa" - /* 6 */ "baaaaaaaaaaa" - /* 7 */ "baaaaaaaaaaa" - /* 8 */ "baaaaabbbbbb" - /* 9 */ "baaaaabbbbbb" - /* 10 */ "bbbbbbbbbbbb" + /* 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 */ ".....cddde.." - /* 1 */ ".ffffffffe.." - /* 2 */ ".ffffffffe.." - /* 3 */ ".fffffffffff" - /* 4 */ ".fffffffffff" - /* 5 */ ".fffffffffff" - /* 6 */ ".fffffffffff" - /* 7 */ ".fffffffffff" - /* 8 */ ".fffff.mmmmm" - /* 9 */ ".fffff.mmmmm" - /* 10 */ ".......mmmmm" + /* 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 */ ".ghhhg......" - /* 2 */ ".h...i......" - /* 3 */ ".h...gf..fff" - /* 4 */ ".h...h...fjf" - /* 5 */ ".h...h...fjf" - /* 6 */ ".h...hkllfjf" - /* 7 */ ".h...gffffff" - /* 8 */ ".h...h.mmmmm" - /* 9 */ ".ghhhg.mmmmm" - /* 10 */ ".......mmmmm" + /* 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 */ "............" - /* 1 */ ".gnnng......" - /* 2 */ ".n...o......" - /* 3 */ ".n...gp..p.f" - /* 4 */ ".n...n.....q" - /* 5 */ ".h...n.....q" - /* 6 */ ".n...n.....q" - /* 7 */ ".n...gfqqqqf" - /* 8 */ ".n...h.mmmmm" - /* 9 */ ".gnnng.mmmmm" - /* 10 */ ".......mmmmm" + /* 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 */ "rrrrrrr....." - /* 1 */ "shhhhhs....." - /* 2 */ ".h...h......" - /* 3 */ ".h..thf..fqf" - /* 4 */ ".h...h...q.f" - /* 5 */ ".h...h...q.f" - /* 6 */ ".hu..h...q.f" - /* 7 */ ".h...hffffff" - /* 8 */ ".h...h.mmmmm" - /* 9 */ "vhhhhhvmmmmm" - /* 10 */ "wwwwwwwmmmmm" + /* 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 */ "rrrrrrr....." - /* 2 */ "shhhhhs....." - /* 3 */ ".h...hxxxxxx" - /* 4 */ ".h...hxyyyyx" - /* 5 */ ".h...hxyyyyx" - /* 6 */ ".h...hxyyyyx" - /* 7 */ ".h...hxxxxxx" - /* 8 */ "vhhhhhvmmmmm" - /* 9 */ "wwwwwwwmmmmm" - /* 10 */ ".......mmmmm" + /* 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 */ "rrrrrrr....." - /* 3 */ "shhhhhs....." - /* 4 */ ".h...h......" - /* 5 */ ".h...h......" - /* 6 */ ".h...h......" - /* 7 */ "vhhhhhv....." - /* 8 */ "wwwwwwwmmmmm" - /* 9 */ ".......mmmmm" - /* 10 */ ".......mmmmm" + /* 2 */ "............" + /* 3 */ "ppppppp....." + /* 4 */ "qfffffq....." + /* 5 */ ".f...f......" + /* 6 */ "tffffft....." + /* 7 */ "uuuuuuu....." + /* 8 */ "............" + /* 9 */ "............" + /* 10 */ "............" // Level 8 /* z\x* 11 */ @@ -515,32 +654,17 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 0 */ "............" /* 1 */ "............" /* 2 */ "............" - /* 3 */ "rrrrrrr....." - /* 4 */ "shhhhhs....." - /* 5 */ ".h...h......" - /* 6 */ "vhhhhhv....." - /* 7 */ "wwwwwww....." - /* 8 */ ".......mmmmm" - /* 9 */ ".......mmmmm" - /* 10 */ ".......mmmmm" - - // Level 9 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "............" - /* 2 */ "............" /* 3 */ "............" - /* 4 */ "rrrrrrr....." - /* 5 */ "hhhhhhh....." - /* 6 */ "wwwwwww....." + /* 4 */ "ppppppp....." + /* 5 */ "fffffff....." + /* 6 */ "uuuuuuu....." /* 7 */ "............" - /* 8 */ ".......mmmmm" - /* 9 */ ".......mmmmm" - /* 10 */ ".......mmmmm", + /* 8 */ "............" + /* 9 */ "............" + /* 10 */ "............", // Connectors: - "-1: 7, 2, -1: 2\n" /* Type -1, direction Z- */, + "-1: 7, 1, -1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -559,20 +683,484 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // 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: 50: 2\n" /* torch */ + "d: 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 */ ".........." + /* 2 */ "..b....b.." + + // Level 2 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "..b....b.." + /* 1 */ ".........." + /* 2 */ "..b....b.." + + // Level 3 + /* z\x* */ + /* * 0123456789 */ + /* 0 */ "..a....a.." + /* 1 */ ".cad..cad." + /* 2 */ "..a....a..", + + // Connectors: + "-3: 0, 1, 1: 4\n" /* Type -3, direction X- */ + "3: 0, 1, 1: 4\n" /* Type 3, direction X- */ + "3: 9, 1, 1: 5\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 */ + "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...m" + /* 1 */ ".a.a." + /* 2 */ "....." + /* 3 */ ".a.a." + /* 4 */ "m...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: + 5, + + // 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 */ + "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...m" + /* 1 */ ".a.a." + /* 2 */ "....." + /* 3 */ ".a.a." + /* 4 */ "m...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: + 5, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + + // MoveToGround: + false, + }, // MineshaftDoubleCrossing + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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, 3, 7, // SizeX = 10, SizeY = 3, SizeZ = 7 + 10, 7, 7, // SizeX = 10, SizeY = 7, SizeZ = 7 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 9, 2, 6, // MaxX, MaxY, MaxZ + 9, 6, 6, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -615,6 +1203,50 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 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: @@ -637,6 +1269,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // SinglePlantBed @@ -646,182 +1281,180 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 58, ID 109, created by Aloe_vera { // Size: - 7, 16, 13, // SizeX = 7, SizeY = 16, SizeZ = 13 + 7, 15, 13, // SizeX = 7, SizeY = 15, SizeZ = 13 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 7, 15, 13, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 7, 14, 13, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "A: 54: 2\n" /* chest */ - "B: 50: 4\n" /* torch */ - "C: 85: 0\n" /* fence */ - "D:126: 8\n" /* woodenslab */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j: 65: 3\n" /* ladder */ - "k: 53: 3\n" /* woodstairs */ - "l: 53: 7\n" /* woodstairs */ + "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: 64:12\n" /* wooddoorblock */ - "o:102: 0\n" /* glasspane */ - "p: 50: 1\n" /* torch */ - "q: 50: 2\n" /* torch */ - "r:171:14\n" /* carpet */ - "s: 50: 3\n" /* torch */ - "t: 53: 2\n" /* woodstairs */ - "u: 53: 0\n" /* woodstairs */ - "v: 53: 1\n" /* woodstairs */ - "w: 53: 5\n" /* woodstairs */ - "x: 53: 4\n" /* woodstairs */ - "y: 17: 4\n" /* tree */ - "z: 17: 8\n" /* tree */, + "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 */ "aaaaaaa" - /* 1 */ "aaaaaaa" - /* 2 */ "aaaaaaa" - /* 3 */ "aaaaaaa" - /* 4 */ "aaaaaaa" - /* 5 */ "aaaaaaa" - /* 6 */ "aaaaaaa" - /* 7 */ "aaaaaaa" - /* 8 */ "aaaaaaa" - /* 9 */ "aaaaaaa" - /* 10 */ "aaaaaaa" - /* 11 */ "aaaaaaa" - /* 12 */ "aaaaaaa" + /* 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 */ "bbaaabb" - /* 1 */ "baaaaab" - /* 2 */ "baaaaab" - /* 3 */ "baaaaab" - /* 4 */ "baaaaab" - /* 5 */ "baaaaab" - /* 6 */ "baaaaab" - /* 7 */ "baaaaab" - /* 8 */ "baaaaab" - /* 9 */ "baaaaab" - /* 10 */ "baaaaab" - /* 11 */ "baaaaab" - /* 12 */ "bbbbbbb" + /* 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 */ "..cde.." - /* 1 */ ".fffff." - /* 2 */ ".fffff." - /* 3 */ ".fffff." - /* 4 */ ".fffff." - /* 5 */ ".fffff." - /* 6 */ ".fffff." - /* 7 */ ".fffff." - /* 8 */ ".fffff." - /* 9 */ ".fffff." - /* 10 */ ".fffff." - /* 11 */ ".fffff." + /* 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 */ ".ghihg." - /* 2 */ ".h..jh." - /* 3 */ ".h...h." - /* 4 */ ".h...h." - /* 5 */ ".gk.kg." - /* 6 */ ".h...h." - /* 7 */ ".hk.kh." - /* 8 */ ".h...h." - /* 9 */ ".h.l.h." - /* 10 */ ".h...h." - /* 11 */ ".ghhhg." + /* 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 */ ".ghnhg." - /* 2 */ ".o..jo." - /* 3 */ ".o...o." - /* 4 */ ".o...o." - /* 5 */ ".g...g." - /* 6 */ ".o...o." - /* 7 */ ".o...o." - /* 8 */ ".hp.qh." - /* 9 */ ".o.r.o." - /* 10 */ ".o...o." - /* 11 */ ".gooog." - /* 12 */ "......." + /* 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 */ ".ghhhg." - /* 2 */ ".h.sjh." - /* 3 */ ".h...h." - /* 4 */ ".h...h." - /* 5 */ "tg...gt" - /* 6 */ "uh...hv" - /* 7 */ "uh...hv" - /* 8 */ "uh...hv" - /* 9 */ "uh...hv" - /* 10 */ "uh...hv" - /* 11 */ "ughhhgv" - /* 12 */ "uw...xv" + /* 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 */ ".gyyyg." - /* 2 */ ".zhhjz." - /* 3 */ ".zhhhz." - /* 4 */ ".zhhhz." - /* 5 */ ".gyyyg." - /* 6 */ ".uh.hv." - /* 7 */ ".uh.hv." - /* 8 */ ".uh.hv." - /* 9 */ ".uh.hv." - /* 10 */ ".uh.hv." - /* 11 */ ".uhhhv." - /* 12 */ ".uw.xv." + /* 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 */ ".ghohg." - /* 2 */ ".h..jh." - /* 3 */ ".h...h." - /* 4 */ ".h.A.h." - /* 5 */ ".ghhhg." - /* 6 */ "..uhv.." - /* 7 */ "..uhv.." - /* 8 */ "..uhv.." - /* 9 */ "..uhv.." - /* 10 */ "..uhv.." - /* 11 */ "..uhv.." - /* 12 */ "..uhv.." + /* 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 */ ".ghohg." - /* 2 */ ".h..jh." - /* 3 */ ".o...o." - /* 4 */ ".h...h." - /* 5 */ ".ghhhg." + /* 1 */ ".eflfe." + /* 2 */ ".f..hf." + /* 3 */ ".f...f." + /* 4 */ ".f.z.f." + /* 5 */ ".efffe." /* 6 */ "......." /* 7 */ "......." /* 8 */ "......." @@ -833,11 +1466,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 9 /* z\x* 0123456 */ /* 0 */ "......." - /* 1 */ ".ghohg." - /* 2 */ ".h..jh." - /* 3 */ ".h...h." - /* 4 */ ".h.B.h." - /* 5 */ ".ghhhg." + /* 1 */ ".ewwwe." + /* 2 */ ".xffhx." + /* 3 */ ".xfffx." + /* 4 */ ".xfffx." + /* 5 */ ".ewwwe." /* 6 */ "......." /* 7 */ "......." /* 8 */ "......." @@ -849,11 +1482,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 10 /* z\x* 0123456 */ /* 0 */ "......." - /* 1 */ ".gyyyg." - /* 2 */ ".zhhjz." - /* 3 */ ".zhhhz." - /* 4 */ ".zhhhz." - /* 5 */ ".gyyyg." + /* 1 */ ".eAAAe." + /* 2 */ ".A...A." + /* 3 */ ".A...A." + /* 4 */ ".A...A." + /* 5 */ ".eAAAe." /* 6 */ "......." /* 7 */ "......." /* 8 */ "......." @@ -865,11 +1498,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 11 /* z\x* 0123456 */ /* 0 */ "......." - /* 1 */ ".gCCCg." - /* 2 */ ".C...C." - /* 3 */ ".C...C." - /* 4 */ ".C...C." - /* 5 */ ".gCCCg." + /* 1 */ ".e...e." + /* 2 */ "......." + /* 3 */ "......." + /* 4 */ "......." + /* 5 */ ".e...e." /* 6 */ "......." /* 7 */ "......." /* 8 */ "......." @@ -880,13 +1513,13 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 12 /* z\x* 0123456 */ - /* 0 */ "......." - /* 1 */ ".g...g." - /* 2 */ "......." - /* 3 */ "......." - /* 4 */ "......." - /* 5 */ ".g...g." - /* 6 */ "......." + /* 0 */ "su...vt" + /* 1 */ "sefffet" + /* 2 */ "sfBBBft" + /* 3 */ "sfBBBft" + /* 4 */ "sfBBBft" + /* 5 */ "sefffet" + /* 6 */ "su...vt" /* 7 */ "......." /* 8 */ "......." /* 9 */ "......." @@ -896,13 +1529,13 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 13 /* z\x* 0123456 */ - /* 0 */ "uw...xv" - /* 1 */ "ughhhgv" - /* 2 */ "uhDDDhv" - /* 3 */ "uhDDDhv" - /* 4 */ "uhDDDhv" - /* 5 */ "ughhhgv" - /* 6 */ "uw...xv" + /* 0 */ ".su.vt." + /* 1 */ ".sffft." + /* 2 */ ".sffft." + /* 3 */ ".sffft." + /* 4 */ ".sffft." + /* 5 */ ".sffft." + /* 6 */ ".su.vt." /* 7 */ "......." /* 8 */ "......." /* 9 */ "......." @@ -912,29 +1545,13 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 14 /* z\x* 0123456 */ - /* 0 */ ".uw.xv." - /* 1 */ ".uhhhv." - /* 2 */ ".uhhhv." - /* 3 */ ".uhhhv." - /* 4 */ ".uhhhv." - /* 5 */ ".uhhhv." - /* 6 */ ".uw.xv." - /* 7 */ "......." - /* 8 */ "......." - /* 9 */ "......." - /* 10 */ "......." - /* 11 */ "......." - /* 12 */ "......." - - // Level 15 - /* z\x* 0123456 */ - /* 0 */ "..uhv.." - /* 1 */ "..uhv.." - /* 2 */ "..uhv.." - /* 3 */ "..uhv.." - /* 4 */ "..uhv.." - /* 5 */ "..uhv.." - /* 6 */ "..uhv.." + /* 0 */ "..sft.." + /* 1 */ "..sft.." + /* 2 */ "..sft.." + /* 3 */ "..sft.." + /* 4 */ "..sft.." + /* 5 */ "..sft.." + /* 6 */ "..sft.." /* 7 */ "......." /* 8 */ "......." /* 9 */ "......." @@ -943,7 +1560,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 12 */ ".......", // Connectors: - "-1: 3, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -962,6 +1579,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenChurchMid @@ -971,132 +1591,118 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 54, ID 105, created by Aloe_vera { // Size: - 7, 8, 9, // SizeX = 7, SizeY = 8, SizeZ = 9 + 7, 7, 9, // SizeX = 7, SizeY = 7, SizeZ = 9 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 7, 7, 9, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 7, 6, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c:170: 0\n" /* haybale */ - "d: 67: 0\n" /* stairs */ - "e: 67: 2\n" /* stairs */ - "f: 67: 1\n" /* stairs */ - "g: 4: 0\n" /* cobblestone */ - "h: 17: 0\n" /* tree */ - "i: 5: 0\n" /* wood */ - "j:170: 4\n" /* haybale */ - "k:170: 8\n" /* haybale */ - "l: 54: 2\n" /* chest */ + "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: 50: 4\n" /* torch */ - "o: 53: 0\n" /* woodstairs */ - "p: 53: 5\n" /* woodstairs */ - "q: 53: 4\n" /* woodstairs */ - "r: 53: 1\n" /* woodstairs */, + "n: 53: 5\n" /* woodstairs */ + "o: 53: 4\n" /* woodstairs */ + "p: 53: 1\n" /* woodstairs */, // Block data: // Level 0 /* z\x* 0123456 */ - /* 0 */ "aaaaaaa" - /* 1 */ "aaaaaaa" - /* 2 */ "aaaaaaa" - /* 3 */ "aaaaaaa" - /* 4 */ "aaaaaaa" - /* 5 */ "aaaaaaa" - /* 6 */ "aaaaaaa" - /* 7 */ "aaaaaaa" - /* 8 */ "aaaaaaa" + /* 0 */ "maaaaam" + /* 1 */ "maaaaam" + /* 2 */ "maaaaam" + /* 3 */ "maaaaam" + /* 4 */ "maaaaam" + /* 5 */ "maaaaam" + /* 6 */ "maaaaam" + /* 7 */ "maaaaam" + /* 8 */ "mmmmmmm" // Level 1 /* z\x* 0123456 */ - /* 0 */ "aaaaaab" - /* 1 */ "baaaaab" - /* 2 */ "baaaaab" - /* 3 */ "baaaaab" - /* 4 */ "baaaaab" - /* 5 */ "baaaaab" - /* 6 */ "baaaaab" - /* 7 */ "baaaaab" - /* 8 */ "bbbbbbb" + /* 0 */ "bcddde." + /* 1 */ ".aaaaa." + /* 2 */ ".aaaaa." + /* 3 */ ".aaaaa." + /* 4 */ ".aaaaa." + /* 5 */ ".aaaaa." + /* 6 */ ".aaaaa." + /* 7 */ ".aaaaa." + /* 8 */ "......." // Level 2 /* z\x* 0123456 */ - /* 0 */ "cdeeef." - /* 1 */ ".ggggg." - /* 2 */ ".ggggg." - /* 3 */ ".ggggg." - /* 4 */ ".ggggg." - /* 5 */ ".ggggg." - /* 6 */ ".ggggg." - /* 7 */ ".ggggg." + /* 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 */ "......." - /* 1 */ ".h..ch." - /* 2 */ ".i...i." - /* 3 */ ".ic.ji." - /* 4 */ ".hkjkh." - /* 5 */ ".iccci." - /* 6 */ ".iklci." - /* 7 */ ".hihih." + /* 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 */ ".n...n." - /* 1 */ ".h...h." - /* 2 */ ".i...i." - /* 3 */ ".i...i." - /* 4 */ ".hj..h." - /* 5 */ ".ijkci." - /* 6 */ ".ijkki." - /* 7 */ ".hihih." - /* 8 */ "......." + /* 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 */ "op...qr" - /* 1 */ "oiiiiir" - /* 2 */ "oi...ir" - /* 3 */ "oi...ir" - /* 4 */ "oi...ir" - /* 5 */ "oicc.ir" - /* 6 */ "oikckir" - /* 7 */ "oiiiiir" - /* 8 */ "op...qr" + /* 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 */ ".op.qr." - /* 1 */ ".oiiir." - /* 2 */ ".oi.ir." - /* 3 */ ".oi.ir." - /* 4 */ ".oi.ir." - /* 5 */ ".oi.ir." - /* 6 */ ".oi.ir." - /* 7 */ ".oiiir." - /* 8 */ ".op.qr." - - // Level 7 - /* z\x* 0123456 */ - /* 0 */ "..oir.." - /* 1 */ "..oir.." - /* 2 */ "..oir.." - /* 3 */ "..oir.." - /* 4 */ "..oir.." - /* 5 */ "..oir.." - /* 6 */ "..oir.." - /* 7 */ "..oir.." - /* 8 */ "..oir..", + /* 0 */ "..lgp.." + /* 1 */ "..lgp.." + /* 2 */ "..lgp.." + /* 3 */ "..lgp.." + /* 4 */ "..lgp.." + /* 5 */ "..lgp.." + /* 6 */ "..lgp.." + /* 7 */ "..lgp.." + /* 8 */ "..lgp..", // Connectors: - "-1: 3, 2, -1: 2\n" /* Type -1, direction Z- */, + "-1: 3, 1, -1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1115,6 +1721,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenGranary @@ -1124,130 +1733,128 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 47, ID 98, created by Aloe_vera { // Size: - 12, 9, 9, // SizeX = 12, SizeY = 9, SizeZ = 9 + 12, 8, 9, // SizeX = 12, SizeY = 8, SizeZ = 9 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 12, 8, 9, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 12, 7, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j: 64: 5\n" /* wooddoorblock */ - "k: 53: 3\n" /* woodstairs */ - "l: 85: 0\n" /* fence */ + "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: 2\n" /* woodstairs */ - "o: 53: 1\n" /* woodstairs */ - "p: 53: 0\n" /* woodstairs */ - "q:102: 0\n" /* glasspane */ - "r: 64:12\n" /* wooddoorblock */ - "s: 50: 3\n" /* torch */ - "t: 72: 0\n" /* woodplate */ - "u: 53: 7\n" /* woodstairs */ - "v: 47: 0\n" /* bookshelf */ - "w: 50: 1\n" /* torch */ - "x: 50: 2\n" /* torch */ - "y: 53: 6\n" /* woodstairs */, + "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 */ "aaaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaaa" - /* 7 */ "aaaaaaaaaaaa" - /* 8 */ "aaaaaaaaaaaa" + /* 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 */ "bbbbaaaabbbb" - /* 1 */ "baaaaaaaaaab" - /* 2 */ "baaaaaaaaaab" - /* 3 */ "baaaaaaaaaab" - /* 4 */ "baaaaaaaaaab" - /* 5 */ "baaaaaaaaaab" - /* 6 */ "baaaaaaaaaab" - /* 7 */ "baaaaaaaaaab" - /* 8 */ "bbbbbbbbbbbb" + /* 0 */ "....bccd...." + /* 1 */ ".aaaaaaaaaa." + /* 2 */ ".aaaaaaaaaa." + /* 3 */ ".aaaaaaaaaa." + /* 4 */ ".aaaaaaaaaa." + /* 5 */ ".aaaaaaaaaa." + /* 6 */ ".aaaaaaaaaa." + /* 7 */ ".aaaaaaaaaa." + /* 8 */ "............" // Level 2 /* z\x* 11 */ /* * 012345678901 */ - /* 0 */ "....cdde...." - /* 1 */ ".ffffffffff." - /* 2 */ ".ffffffffff." - /* 3 */ ".ffffffffff." - /* 4 */ ".ffffffffff." - /* 5 */ ".ffffffffff." - /* 6 */ ".ffffffffff." - /* 7 */ ".ffffffffff." + /* 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 */ ".ghhhijhhhg." - /* 2 */ ".h........h." - /* 3 */ ".hk......kh." - /* 4 */ ".hl......lh." - /* 5 */ ".hn......nh." - /* 6 */ ".h.olpolp.h." - /* 7 */ ".ghhhhhhhhg." + /* 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 */ "............" - /* 1 */ ".gqqhrrhqqg." - /* 2 */ ".q..s..s..q." - /* 3 */ ".q........q." - /* 4 */ ".ht......th." - /* 5 */ ".q........q." - /* 6 */ ".q..t..t..q." - /* 7 */ ".gqqhqqhqqg." - /* 8 */ "............" + /* 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 */ "nnnnnnnnnnnn" - /* 1 */ "uhhhhhhhhhhu" - /* 2 */ ".hvvvvvvvvh." - /* 3 */ ".h........h." - /* 4 */ ".hw......xh." - /* 5 */ ".h........h." - /* 6 */ ".hvvvvvvvvh." - /* 7 */ "yhhhhhhhhhhy" - /* 8 */ "kkkkkkkkkkkk" + /* 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 */ "nnnnnnnnnnnn" - /* 2 */ "uhhhhhhhhhhu" - /* 3 */ ".hvvvvvvvvh." - /* 4 */ ".h........h." - /* 5 */ ".hvvvvvvvvh." - /* 6 */ "yhhhhhhhhhhy" - /* 7 */ "kkkkkkkkkkkk" + /* 1 */ "............" + /* 2 */ "kkkkkkkkkkkk" + /* 3 */ "sffffffffffs" + /* 4 */ ".f........f." + /* 5 */ "wffffffffffw" + /* 6 */ "iiiiiiiiiiii" + /* 7 */ "............" /* 8 */ "............" // Level 7 @@ -1255,29 +1862,16 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* * 012345678901 */ /* 0 */ "............" /* 1 */ "............" - /* 2 */ "nnnnnnnnnnnn" - /* 3 */ "uhhhhhhhhhhu" - /* 4 */ ".h........h." - /* 5 */ "yhhhhhhhhhhy" - /* 6 */ "kkkkkkkkkkkk" - /* 7 */ "............" - /* 8 */ "............" - - // Level 8 - /* z\x* 11 */ - /* * 012345678901 */ - /* 0 */ "............" - /* 1 */ "............" /* 2 */ "............" - /* 3 */ "nnnnnnnnnnnn" - /* 4 */ "hhhhhhhhhhhh" - /* 5 */ "kkkkkkkkkkkk" + /* 3 */ "kkkkkkkkkkkk" + /* 4 */ "ffffffffffff" + /* 5 */ "iiiiiiiiiiii" /* 6 */ "............" /* 7 */ "............" /* 8 */ "............", // Connectors: - "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1296,6 +1890,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouse10x7Library @@ -1305,115 +1902,103 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 49, ID 100, created by Aloe_vera { // Size: - 7, 8, 7, // SizeX = 7, SizeY = 8, SizeZ = 7 + 7, 7, 7, // SizeX = 7, SizeY = 7, SizeZ = 7 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 7, 7, 7, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 7, 6, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j: 64:12\n" /* wooddoorblock */ - "k:102: 0\n" /* glasspane */ - "l: 53: 2\n" /* woodstairs */ + "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: 7\n" /* woodstairs */ - "o: 50: 3\n" /* torch */ - "p: 53: 6\n" /* woodstairs */ - "q: 53: 3\n" /* woodstairs */, + "n: 53: 6\n" /* woodstairs */ + "o: 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" + /* 0 */ "mmaaamm" + /* 1 */ "maaaaam" + /* 2 */ "maaaaam" + /* 3 */ "maaaaam" + /* 4 */ "maaaaam" + /* 5 */ "maaaaam" + /* 6 */ "mmmmmmm" // Level 1 /* z\x* 0123456 */ - /* 0 */ "bbaaabb" - /* 1 */ "baaaaab" - /* 2 */ "baaaaab" - /* 3 */ "baaaaab" - /* 4 */ "baaaaab" - /* 5 */ "baaaaab" - /* 6 */ "bbbbbbb" + /* 0 */ "..bcd.." + /* 1 */ ".aaaaa." + /* 2 */ ".aaaaa." + /* 3 */ ".aaaaa." + /* 4 */ ".aaaaa." + /* 5 */ ".aaaaa." + /* 6 */ "......." // Level 2 /* z\x* 0123456 */ - /* 0 */ "..cde.." - /* 1 */ ".fffff." - /* 2 */ ".fffff." - /* 3 */ ".fffff." - /* 4 */ ".fffff." - /* 5 */ ".fffff." + /* 0 */ "......." + /* 1 */ ".efgfe." + /* 2 */ ".f...f." + /* 3 */ ".f...f." + /* 4 */ ".f...f." + /* 5 */ ".efffe." /* 6 */ "......." // Level 3 /* z\x* 0123456 */ /* 0 */ "......." - /* 1 */ ".ghihg." - /* 2 */ ".h...h." - /* 3 */ ".h...h." - /* 4 */ ".h...h." - /* 5 */ ".ghhhg." + /* 1 */ ".efhfe." + /* 2 */ ".i...i." + /* 3 */ ".i...i." + /* 4 */ ".i...i." + /* 5 */ ".eiiie." /* 6 */ "......." // Level 4 /* z\x* 0123456 */ - /* 0 */ "......." - /* 1 */ ".ghjhg." - /* 2 */ ".k...k." - /* 3 */ ".k...k." - /* 4 */ ".k...k." - /* 5 */ ".gkkkg." - /* 6 */ "......." + /* 0 */ "jjjjjjj" + /* 1 */ "kfffffk" + /* 2 */ ".fl.lf." + /* 3 */ ".f...f." + /* 4 */ ".f...f." + /* 5 */ "nfffffn" + /* 6 */ "ooooooo" // Level 5 /* z\x* 0123456 */ - /* 0 */ "lllllll" - /* 1 */ "nhhhhhn" - /* 2 */ ".ho.oh." - /* 3 */ ".h...h." - /* 4 */ ".h...h." - /* 5 */ "phhhhhp" - /* 6 */ "qqqqqqq" + /* 0 */ "......." + /* 1 */ "jjjjjjj" + /* 2 */ "kfffffk" + /* 3 */ ".f...f." + /* 4 */ "nfffffn" + /* 5 */ "ooooooo" + /* 6 */ "......." // Level 6 /* z\x* 0123456 */ /* 0 */ "......." - /* 1 */ "lllllll" - /* 2 */ "nhhhhhn" - /* 3 */ ".h...h." - /* 4 */ "phhhhhp" - /* 5 */ "qqqqqqq" - /* 6 */ "......." - - // Level 7 - /* z\x* 0123456 */ - /* 0 */ "......." /* 1 */ "......." - /* 2 */ "lllllll" - /* 3 */ "hhhhhhh" - /* 4 */ "qqqqqqq" + /* 2 */ "jjjjjjj" + /* 3 */ "fffffff" + /* 4 */ "ooooooo" /* 5 */ "......." /* 6 */ ".......", // Connectors: - "-1: 3, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 3, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1432,6 +2017,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouse5x5 @@ -1441,115 +2029,103 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 40, ID 91, created by xoft { // Size: - 9, 8, 7, // SizeX = 9, SizeY = 8, SizeZ = 7 + 9, 7, 7, // SizeX = 9, SizeY = 7, SizeZ = 7 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 9, 7, 7, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 9, 6, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j:102: 0\n" /* glasspane */ - "k: 64:12\n" /* wooddoorblock */ - "l: 53: 2\n" /* woodstairs */ + "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: 7\n" /* woodstairs */ - "o: 50: 3\n" /* torch */ - "p: 53: 6\n" /* woodstairs */ - "q: 53: 3\n" /* woodstairs */, + "n: 53: 6\n" /* woodstairs */ + "o: 53: 3\n" /* woodstairs */, // Block data: // Level 0 /* z\x* 012345678 */ - /* 0 */ "aaaaaaaaa" - /* 1 */ "aaaaaaaaa" - /* 2 */ "aaaaaaaaa" - /* 3 */ "aaaaaaaaa" - /* 4 */ "aaaaaaaaa" - /* 5 */ "aaaaaaaaa" - /* 6 */ "aaaaaaaaa" + /* 0 */ "mmmaaammm" + /* 1 */ "maaaaaaam" + /* 2 */ "maaaaaaam" + /* 3 */ "maaaaaaam" + /* 4 */ "maaaaaaam" + /* 5 */ "maaaaaaam" + /* 6 */ "mmmmmmmmm" // Level 1 /* z\x* 012345678 */ - /* 0 */ "bbbaaabbb" - /* 1 */ "baaaaaaab" - /* 2 */ "baaaaaaab" - /* 3 */ "baaaaaaab" - /* 4 */ "baaaaaaab" - /* 5 */ "baaaaaaab" - /* 6 */ "bbbbbbbbb" + /* 0 */ "...bcd..." + /* 1 */ ".aaaaaaa." + /* 2 */ ".aaaaaaa." + /* 3 */ ".aaaaaaa." + /* 4 */ ".aaaaaaa." + /* 5 */ ".aaaaaaa." + /* 6 */ "........." // Level 2 /* z\x* 012345678 */ - /* 0 */ "...cde..." - /* 1 */ ".fffffff." - /* 2 */ ".fffffff." - /* 3 */ ".fffffff." - /* 4 */ ".fffffff." - /* 5 */ ".fffffff." + /* 0 */ "........." + /* 1 */ ".effgffe." + /* 2 */ ".f.....f." + /* 3 */ ".f.....f." + /* 4 */ ".f.....f." + /* 5 */ ".efffffe." /* 6 */ "........." // Level 3 /* z\x* 012345678 */ /* 0 */ "........." - /* 1 */ ".ghhihhg." + /* 1 */ ".ehfifhe." /* 2 */ ".h.....h." /* 3 */ ".h.....h." /* 4 */ ".h.....h." - /* 5 */ ".ghhhhhg." + /* 5 */ ".ehhfhhe." /* 6 */ "........." // Level 4 /* z\x* 012345678 */ - /* 0 */ "........." - /* 1 */ ".gjhkhjg." - /* 2 */ ".j.....j." - /* 3 */ ".j.....j." - /* 4 */ ".j.....j." - /* 5 */ ".gjjhjjg." - /* 6 */ "........." + /* 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 */ "lllllllll" - /* 1 */ "nghhhhhgn" - /* 2 */ ".h.o.o.h." - /* 3 */ ".h.....h." - /* 4 */ ".h.....h." - /* 5 */ "pghhhhhgp" - /* 6 */ "qqqqqqqqq" + /* 0 */ "........." + /* 1 */ "jjjjjjjjj" + /* 2 */ "kfffffffk" + /* 3 */ ".f.....f." + /* 4 */ "nfffffffn" + /* 5 */ "ooooooooo" + /* 6 */ "........." // Level 6 /* z\x* 012345678 */ /* 0 */ "........." - /* 1 */ "lllllllll" - /* 2 */ "nhhhhhhhn" - /* 3 */ ".h.....h." - /* 4 */ "phhhhhhhp" - /* 5 */ "qqqqqqqqq" - /* 6 */ "........." - - // Level 7 - /* z\x* 012345678 */ - /* 0 */ "........." /* 1 */ "........." - /* 2 */ "lllllllll" - /* 3 */ "hhhhhhhhh" - /* 4 */ "qqqqqqqqq" + /* 2 */ "jjjjjjjjj" + /* 3 */ "fffffffff" + /* 4 */ "ooooooooo" /* 5 */ "........." /* 6 */ ".........", // Connectors: - "-1: 4, 2, -1: 2\n" /* Type -1, direction Z- */, + "-1: 4, 1, -1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1568,6 +2144,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouse7x5 @@ -1577,274 +2156,110 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 41, ID 92, created by xoft { // Size: - 11, 8, 7, // SizeX = 11, SizeY = 8, SizeZ = 7 + 11, 7, 7, // SizeX = 11, SizeY = 7, SizeZ = 7 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 11, 7, 7, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 11, 6, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j:102: 0\n" /* glasspane */ - "k: 64:12\n" /* wooddoorblock */ - "l: 53: 2\n" /* woodstairs */ + "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: 7\n" /* woodstairs */ - "o: 50: 3\n" /* torch */ - "p: 53: 6\n" /* woodstairs */ - "q: 53: 3\n" /* woodstairs */, + "n: 53: 6\n" /* woodstairs */ + "o: 53: 3\n" /* woodstairs */, // Block data: // Level 0 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "aaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaa" + /* 0 */ "mmmmaaammmm" + /* 1 */ "maaaaaaaaam" + /* 2 */ "maaaaaaaaam" + /* 3 */ "maaaaaaaaam" + /* 4 */ "maaaaaaaaam" + /* 5 */ "maaaaaaaaam" + /* 6 */ "mmmmmmmmmmm" // Level 1 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "bbbbaaabbbb" - /* 1 */ "baaaaaaaaab" - /* 2 */ "baaaaaaaaab" - /* 3 */ "baaaaaaaaab" - /* 4 */ "baaaaaaaaab" - /* 5 */ "baaaaaaaaab" - /* 6 */ "bbbbbbbbbbb" + /* 0 */ "....bcd...." + /* 1 */ ".aaaaaaaaa." + /* 2 */ ".aaaaaaaaa." + /* 3 */ ".aaaaaaaaa." + /* 4 */ ".aaaaaaaaa." + /* 5 */ ".aaaaaaaaa." + /* 6 */ "..........." // Level 2 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "....cde...." - /* 1 */ ".fffffffff." - /* 2 */ ".fffffffff." - /* 3 */ ".fffffffff." - /* 4 */ ".fffffffff." - /* 5 */ ".fffffffff." + /* 0 */ "..........." + /* 1 */ ".efffgfffe." + /* 2 */ ".f.......f." + /* 3 */ ".f.......f." + /* 4 */ ".f.......f." + /* 5 */ ".efffffffe." /* 6 */ "..........." // Level 3 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ ".ghhhihhhg." + /* 1 */ ".ehhfifhhe." /* 2 */ ".h.......h." /* 3 */ ".h.......h." /* 4 */ ".h.......h." - /* 5 */ ".ghhhhhhhg." + /* 5 */ ".ehhhfhhhe." /* 6 */ "..........." // Level 4 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".gjjhkhjjg." - /* 2 */ ".j.......j." - /* 3 */ ".j.......j." - /* 4 */ ".j.......j." - /* 5 */ ".gjjjhjjjg." - /* 6 */ "..........." + /* 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 */ "lllllllllll" - /* 1 */ "nhhhhhhhhhn" - /* 2 */ ".h..o.o.hh." - /* 3 */ ".h......hh." - /* 4 */ ".h......hh." - /* 5 */ "phhhhhhhhhp" - /* 6 */ "qqqqqqqqqqq" - - // Level 6 - /* z\x* 1 */ - /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ "lllllllllll" - /* 2 */ "nhhhhhhhhhn" - /* 3 */ ".hhhhhhhhh." - /* 4 */ "phhhhhhhhhp" - /* 5 */ "qqqqqqqqqqq" - /* 6 */ "..........." - - // Level 7 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "lllllllllll" - /* 3 */ "hhhhhhhhhhh" - /* 4 */ "qqqqqqqqqqq" - /* 5 */ "..........." - /* 6 */ "...........", - - // Connectors: - "-1: 5, 2, -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, - }, // WoodenHouse9x5 - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // WoodenHouse9x5: - // The data has been exported from the gallery Plains, area index 46, ID 97, created by Aloe_vera - { - // Size: - 11, 8, 7, // SizeX = 11, SizeY = 8, SizeZ = 7 - - // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 11, 7, 7, // MaxX, MaxY, MaxZ - - // Block definitions: - ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j: 53: 3\n" /* woodstairs */ - "k: 85: 0\n" /* fence */ - "l: 53: 2\n" /* woodstairs */ - "m: 19: 0\n" /* sponge */ - "n: 53: 1\n" /* woodstairs */ - "o: 53: 0\n" /* woodstairs */ - "p:102: 0\n" /* glasspane */ - "q: 64:12\n" /* wooddoorblock */ - "r: 50: 3\n" /* torch */ - "s: 72: 0\n" /* woodplate */ - "t: 53: 7\n" /* woodstairs */ - "u: 47: 0\n" /* bookshelf */ - "v: 50: 1\n" /* torch */ - "w: 50: 2\n" /* torch */ - "x: 53: 6\n" /* woodstairs */, - - // Block data: - // Level 0 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "aaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaa" - - // Level 1 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "bbbbaaabbbb" - /* 1 */ "baaaaaaaaab" - /* 2 */ "baaaaaaaaab" - /* 3 */ "baaaaaaaaab" - /* 4 */ "baaaaaaaaab" - /* 5 */ "baaaaaaaaab" - /* 6 */ "bbbbbbbbbbb" - - // Level 2 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "....cde...." - /* 1 */ ".fffffffff." - /* 2 */ ".fffffffff." + /* 1 */ "jjjjjjjjjjj" + /* 2 */ "kfffffffffk" /* 3 */ ".fffffffff." - /* 4 */ ".fffffffff." - /* 5 */ ".fffffffff." + /* 4 */ "nfffffffffn" + /* 5 */ "ooooooooooo" /* 6 */ "..........." - // Level 3 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".ghhhihhhg." - /* 2 */ ".hj.....jh." - /* 3 */ ".hk.....kh." - /* 4 */ ".hl.nko.lh." - /* 5 */ ".ghhhhhhhg." - /* 6 */ "..........." - - // Level 4 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".gpphqhppg." - /* 2 */ ".p..r.r..p." - /* 3 */ ".ps.....sp." - /* 4 */ ".p...s...p." - /* 5 */ ".gppphpppg." - /* 6 */ "..........." - - // Level 5 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "lllllllllll" - /* 1 */ "thhhhhhhhht" - /* 2 */ ".huuuuuuuh." - /* 3 */ ".hv.....wh." - /* 4 */ ".huuuuuuuh." - /* 5 */ "xhhhhhhhhhx" - /* 6 */ "jjjjjjjjjjj" - // Level 6 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ "lllllllllll" - /* 2 */ "thhhhhhhhht" - /* 3 */ ".h.......h." - /* 4 */ "xhhhhhhhhhx" - /* 5 */ "jjjjjjjjjjj" - /* 6 */ "..........." - - // Level 7 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." /* 1 */ "..........." - /* 2 */ "lllllllllll" - /* 3 */ "hhhhhhhhhhh" - /* 4 */ "jjjjjjjjjjj" + /* 2 */ "jjjjjjjjjjj" + /* 3 */ "fffffffffff" + /* 4 */ "ooooooooooo" /* 5 */ "..........." /* 6 */ "...........", // Connectors: - "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 5, 1, -1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1863,6 +2278,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouse9x5 @@ -1893,11 +2311,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = "k: 85: 0\n" /* fence */ "l: 53: 0\n" /* woodstairs */ "m: 19: 0\n" /* sponge */ - "n: 64: 2\n" /* wooddoorblock */ - "o: 64: 0\n" /* wooddoorblock */ + "n: 64: 6\n" /* wooddoorblock */ + "o: 64: 4\n" /* wooddoorblock */ "p:102: 0\n" /* glasspane */ "q: 72: 0\n" /* woodplate */ - "r: 64: 8\n" /* wooddoorblock */ + "r: 64:12\n" /* wooddoorblock */ "s: 53: 5\n" /* woodstairs */ "t: 53: 4\n" /* woodstairs */ "u: 50: 1\n" /* torch */ @@ -2029,162 +2447,129 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouse9x5Fence /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // WoodenHouse9x7: - // The data has been exported from the gallery Plains, area index 52, ID 103, created by Aloe_vera + // WoodenHouse9x5Library: + // The data has been exported from the gallery Plains, area index 46, ID 97, created by Aloe_vera { // Size: - 11, 9, 9, // SizeX = 11, SizeY = 9, SizeZ = 9 + 11, 7, 7, // SizeX = 11, SizeY = 7, SizeZ = 7 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 11, 8, 9, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 11, 6, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j:102: 0\n" /* glasspane */ - "k: 64:12\n" /* wooddoorblock */ - "l: 53: 2\n" /* woodstairs */ + "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: 53: 7\n" /* woodstairs */ - "o: 50: 3\n" /* torch */ - "p: 50: 4\n" /* torch */ - "q: 53: 6\n" /* woodstairs */ - "r: 53: 3\n" /* woodstairs */, + "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 */ "aaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaa" - /* 7 */ "aaaaaaaaaaa" - /* 8 */ "aaaaaaaaaaa" + /* 0 */ "mmmmaaammmm" + /* 1 */ "maaaaaaaaam" + /* 2 */ "maaaaaaaaam" + /* 3 */ "maaaaaaaaam" + /* 4 */ "maaaaaaaaam" + /* 5 */ "maaaaaaaaam" + /* 6 */ "mmmmmmmmmmm" // Level 1 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "bbbbaaabbbb" - /* 1 */ "baaaaaaaaab" - /* 2 */ "baaaaaaaaab" - /* 3 */ "baaaaaaaaab" - /* 4 */ "baaaaaaaaab" - /* 5 */ "baaaaaaaaab" - /* 6 */ "baaaaaaaaab" - /* 7 */ "baaaaaaaaab" - /* 8 */ "bbbbbbbbbbb" + /* 0 */ "....bcd...." + /* 1 */ ".aaaaaaaaa." + /* 2 */ ".aaaaaaaaa." + /* 3 */ ".aaaaaaaaa." + /* 4 */ ".aaaaaaaaa." + /* 5 */ ".aaaaaaaaa." + /* 6 */ "..........." // Level 2 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "....cde...." - /* 1 */ ".fffffffff." - /* 2 */ ".fffffffff." - /* 3 */ ".fffffffff." - /* 4 */ ".fffffffff." - /* 5 */ ".fffffffff." - /* 6 */ ".fffffffff." - /* 7 */ ".fffffffff." - /* 8 */ "..........." + /* 0 */ "..........." + /* 1 */ ".efffgfffe." + /* 2 */ ".fh.....hf." + /* 3 */ ".fi.....if." + /* 4 */ ".fj.kil.jf." + /* 5 */ ".efffffffe." + /* 6 */ "..........." // Level 3 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ ".ghhhihhhg." - /* 2 */ ".h.......h." - /* 3 */ ".h.......h." - /* 4 */ ".h.......h." - /* 5 */ ".h.......h." - /* 6 */ ".h.......h." - /* 7 */ ".ghhhhhhhg." - /* 8 */ "..........." + /* 1 */ ".ennfofnne." + /* 2 */ ".n..p.p..n." + /* 3 */ ".nq.....qn." + /* 4 */ ".n...q...n." + /* 5 */ ".ennnfnnne." + /* 6 */ "..........." // Level 4 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".gjjhkhjjg." - /* 2 */ ".j.......j." - /* 3 */ ".j.......j." - /* 4 */ ".h.......h." - /* 5 */ ".j.......j." - /* 6 */ ".j.......j." - /* 7 */ ".gjjjhjjjg." - /* 8 */ "..........." + /* 0 */ "jjjjjjjjjjj" + /* 1 */ "rfffffffffr" + /* 2 */ ".fsssssssf." + /* 3 */ ".ft.....uf." + /* 4 */ ".fsssssssf." + /* 5 */ "vfffffffffv" + /* 6 */ "hhhhhhhhhhh" // Level 5 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "lllllllllll" - /* 1 */ "nhhhhhhhhhn" - /* 2 */ ".h..o.o..h." - /* 3 */ ".h.......h." - /* 4 */ ".h.......h." - /* 5 */ ".h.......h." - /* 6 */ ".h...p...h." - /* 7 */ "qhhhhhhhhhq" - /* 8 */ "rrrrrrrrrrr" + /* 0 */ "..........." + /* 1 */ "jjjjjjjjjjj" + /* 2 */ "rfffffffffr" + /* 3 */ ".f.......f." + /* 4 */ "vfffffffffv" + /* 5 */ "hhhhhhhhhhh" + /* 6 */ "..........." // Level 6 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "..........." - /* 1 */ "lllllllllll" - /* 2 */ "nhhhhhhhhhn" - /* 3 */ ".h.......h." - /* 4 */ ".h.......h." - /* 5 */ ".h.......h." - /* 6 */ "qhhhhhhhhhq" - /* 7 */ "rrrrrrrrrrr" - /* 8 */ "..........." - - // Level 7 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." /* 1 */ "..........." - /* 2 */ "lllllllllll" - /* 3 */ "nhhhhhhhhhn" - /* 4 */ ".h.......h." - /* 5 */ "qhhhhhhhhhq" - /* 6 */ "rrrrrrrrrrr" - /* 7 */ "..........." - /* 8 */ "..........." - - // Level 8 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." - /* 2 */ "..........." - /* 3 */ "lllllllllll" + /* 2 */ "jjjjjjjjjjj" + /* 3 */ "fffffffffff" /* 4 */ "hhhhhhhhhhh" - /* 5 */ "rrrrrrrrrrr" - /* 6 */ "..........." - /* 7 */ "..........." - /* 8 */ "...........", + /* 5 */ "..........." + /* 6 */ "...........", // Connectors: - "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2203,6 +2588,171 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // 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 @@ -2246,19 +2796,19 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 0 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "aaaaaaaaaaa" - /* 1 */ "aaaaaaaaaab" - /* 2 */ "aaaaaaaaaab" - /* 3 */ "aaaaaaaaaab" - /* 4 */ "aaaaaaaaaab" - /* 5 */ "aaaaaaaaaaa" - /* 6 */ "aaaaaaaaaab" - /* 7 */ "aaaaaaaaaab" - /* 8 */ "abaaaaaaabb" - /* 9 */ "aaaaaaaaabb" - /* 10 */ "aaaaaaaaabb" - /* 11 */ "abaaaaaaaba" - /* 12 */ "abaaaaaaabb" + /* 0 */ "abaaaaabbbb" + /* 1 */ "baaaaaaaaab" + /* 2 */ "baaaaaaaaab" + /* 3 */ "baaaaaaaaab" + /* 4 */ "baaaaaaaaab" + /* 5 */ "baaaaaaaaab" + /* 6 */ "baaaaaaaaab" + /* 7 */ "baaaaaaaaab" + /* 8 */ "bbaaaaaaabb" + /* 9 */ "bbaaaaaaabb" + /* 10 */ "bbaaaaaaabb" + /* 11 */ "bbaaaaaaabb" + /* 12 */ "bbaaaaaaabb" // Level 1 /* z\x* 1 */ @@ -2416,6 +2966,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouse9x7Butcher @@ -2425,126 +2978,124 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 38, ID 87, created by Aloe_vera { // Size: - 11, 9, 9, // SizeX = 11, SizeY = 9, SizeZ = 9 + 11, 8, 9, // SizeX = 11, SizeY = 8, SizeZ = 9 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 11, 8, 9, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 11, 7, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 67: 3\n" /* stairs */ - "h: 17: 0\n" /* tree */ - "i: 5: 0\n" /* wood */ - "j: 64: 7\n" /* wooddoorblock */ - "k:102: 0\n" /* glasspane */ - "l: 64:12\n" /* wooddoorblock */ + "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: 53: 2\n" /* woodstairs */ - "o: 53: 7\n" /* woodstairs */ - "p: 17: 4\n" /* tree */ - "q: 17: 8\n" /* tree */ - "r: 50: 3\n" /* torch */ - "s: 50: 4\n" /* torch */ - "t: 53: 6\n" /* woodstairs */ - "u: 53: 3\n" /* woodstairs */, + "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 */ "aaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaa" - /* 7 */ "aaaaaaaaaaa" - /* 8 */ "aaaaaaaaaaa" + /* 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 */ "bbbbaaabbbb" - /* 1 */ "baaaaaaaaab" - /* 2 */ "baaaaaaaaab" - /* 3 */ "baaaaaaaaab" - /* 4 */ "baaaaaaaaab" - /* 5 */ "baaaaaaaaab" - /* 6 */ "baaaaaaaaab" - /* 7 */ "baaaaaaaaab" - /* 8 */ "bbbbaaabbbb" + /* 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 */ "....cde...." - /* 1 */ ".fffffffff." - /* 2 */ ".fffffffff." - /* 3 */ ".fffffffff." - /* 4 */ ".fffffffff." - /* 5 */ ".fffffffff." - /* 6 */ ".fffffffff." - /* 7 */ ".fffffffff." - /* 8 */ "....cge...." + /* 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 */ ".hiihjhiih." + /* 1 */ ".fiifjfiif." /* 2 */ ".i.......i." /* 3 */ ".i.......i." - /* 4 */ ".h.......h." + /* 4 */ ".f.......f." /* 5 */ ".i.......i." /* 6 */ ".i.......i." - /* 7 */ ".hiihjhiih." + /* 7 */ ".fiifjfiif." /* 8 */ "..........." // Level 4 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".hkkhlhkkh." - /* 2 */ ".k.......k." - /* 3 */ ".k.......k." - /* 4 */ ".h.......h." - /* 5 */ ".k.......k." - /* 6 */ ".k.......k." - /* 7 */ ".hkkhlhkkh." - /* 8 */ "..........." + /* 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 */ "nnnnnnnnnnn" - /* 1 */ "ohpppppppho" - /* 2 */ ".q..r.r..q." - /* 3 */ ".q.......q." - /* 4 */ ".q.......q." - /* 5 */ ".q.......q." - /* 6 */ ".q..s.s..q." - /* 7 */ "thpppppppht" - /* 8 */ "uuuuuuuuuuu" + /* 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 */ "nnnnnnnnnnn" - /* 2 */ "oiiiiiiiiio" - /* 3 */ ".i.......i." - /* 4 */ ".i.......i." - /* 5 */ ".i.......i." - /* 6 */ "tiiiiiiiiit" - /* 7 */ "uuuuuuuuuuu" + /* 1 */ "..........." + /* 2 */ "kkkkkkkkkkk" + /* 3 */ "lgggggggggl" + /* 4 */ ".g.......g." + /* 5 */ "rgggggggggr" + /* 6 */ "sssssssssss" + /* 7 */ "..........." /* 8 */ "..........." // Level 7 @@ -2552,29 +3103,16 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* * 01234567890 */ /* 0 */ "..........." /* 1 */ "..........." - /* 2 */ "nnnnnnnnnnn" - /* 3 */ "oiiiiiiiiio" - /* 4 */ ".i.......i." - /* 5 */ "tiiiiiiiiit" - /* 6 */ "uuuuuuuuuuu" - /* 7 */ "..........." - /* 8 */ "..........." - - // Level 8 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ "..........." /* 2 */ "..........." - /* 3 */ "nnnnnnnnnnn" - /* 4 */ "iiiiiiiiiii" - /* 5 */ "uuuuuuuuuuu" + /* 3 */ "kkkkkkkkkkk" + /* 4 */ "ggggggggggg" + /* 5 */ "sssssssssss" /* 6 */ "..........." /* 7 */ "..........." /* 8 */ "...........", // Connectors: - "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2593,6 +3131,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouse9x7DoubleDoor @@ -2602,250 +3143,228 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 39, ID 90, created by STR_Warrior { // Size: - 15, 10, 16, // SizeX = 15, SizeY = 10, SizeZ = 16 + 15, 9, 16, // SizeX = 15, SizeY = 9, SizeZ = 16 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 15, 9, 16, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 15, 8, 16, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "A: 50: 4\n" /* torch */ - "B: 50: 2\n" /* torch */ - "C: 53: 7\n" /* woodstairs */ - "D: 53: 4\n" /* woodstairs */ - "E: 53: 5\n" /* woodstairs */ - "F: 53: 6\n" /* woodstairs */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 43: 0\n" /* doubleslab */ - "h: 17: 0\n" /* tree */ - "i: 5: 0\n" /* wood */ - "j: 64: 7\n" /* wooddoorblock */ - "k: 96: 8\n" /* trapdoor */ - "l: 61: 2\n" /* furnace */ + "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: 3\n" /* woodstairs */ - "o: 85: 0\n" /* fence */ - "p: 53: 2\n" /* woodstairs */ - "q: 53: 1\n" /* woodstairs */ - "r: 53: 0\n" /* woodstairs */ - "s: 47: 0\n" /* bookshelf */ - "t:102: 0\n" /* glasspane */ - "u: 64:12\n" /* wooddoorblock */ - "v: 72: 0\n" /* woodplate */ - "w: 17: 4\n" /* tree */ - "x: 17: 8\n" /* tree */ - "y: 50: 3\n" /* torch */ - "z: 50: 1\n" /* torch */, + "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 */ "aaaaaaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaaaaaa" - /* 7 */ "aaaaaaaaaaaaaaa" - /* 8 */ "mmmmmmmmaaaaaaa" - /* 9 */ "mmmmmmmmaaaaaaa" - /* 10 */ "mmmmmmmmaaaaaaa" - /* 11 */ "mmmmmmmmaaaaaaa" - /* 12 */ "mmmmmmmmaaaaaaa" - /* 13 */ "mmmmmmmmaaaaaaa" - /* 14 */ "mmmmmmmmaaaaaaa" - /* 15 */ "mmmmmmmmaaaaaaa" + /* 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 */ "bbbbbbaaabbbbbb" - /* 1 */ "baaaaaaaaaaaaab" - /* 2 */ "baaaaaaaaaaaaab" - /* 3 */ "baaaaaaaaaaaaab" - /* 4 */ "baaaaaaaaaaaaab" - /* 5 */ "baaaaaaaaaaaaab" - /* 6 */ "baaaaaaaaaaaaab" - /* 7 */ "baaaaaaaaaaaaab" - /* 8 */ "mmmmmmmmaaaaaab" - /* 9 */ "mmmmmmmmaaaaaab" - /* 10 */ "mmmmmmmmaaaaaab" - /* 11 */ "mmmmmmmmaaaaaab" - /* 12 */ "mmmmmmmmaaaaaab" - /* 13 */ "mmmmmmmmaaaaaab" - /* 14 */ "mmmmmmmmaaaaaab" - /* 15 */ "mmmmmmmmbbbbbbb" + /* 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 */ "......cde......" - /* 1 */ ".fffffffffffff." - /* 2 */ ".fggggffffffff." - /* 3 */ ".fggggffffffff." - /* 4 */ ".fffffffffffff." - /* 5 */ ".fffffffffffff." - /* 6 */ ".fffffffffffff." - /* 7 */ "mfffffffffffff." - /* 8 */ "mmmmmmmmffffff." - /* 9 */ "mmmmmmmmffffff." - /* 10 */ "mmmmmmmmffffff." - /* 11 */ "mmmmmmmmffffff." - /* 12 */ "mmmmmmmmffffff." - /* 13 */ "mmmmmmmmffffff." - /* 14 */ "mmmmmmmmffffff." - /* 15 */ "mmmmmmmm......." + /* 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 */ ".hiiiihjhiiiih." - /* 2 */ ".i...k.......i." - /* 3 */ ".ilggg......ni." - /* 4 */ ".h..........oi." - /* 5 */ ".i..........pi." - /* 6 */ ".i.qor..qo...i." - /* 7 */ "mhiiiiiihp...h." - /* 8 */ "mmmmmmmmi....i." - /* 9 */ "mmmmmmmmin...i." - /* 10 */ "mmmmmmmmio..ni." - /* 11 */ "mmmmmmmmip..oi." - /* 12 */ "mmmmmmmmi...pi." - /* 13 */ "mmmmmmmmis..si." - /* 14 */ "mmmmmmmmhiiiih." - /* 15 */ "mmmmmmmm......." + /* 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 */ ".hittihuhittih." - /* 2 */ ".i...........i." - /* 3 */ ".i...........t." - /* 4 */ ".h..........vt." - /* 5 */ ".i...........t." - /* 6 */ ".i..v....v...i." - /* 7 */ "mhittttih....h." - /* 8 */ "mmmmmmmmi....i." - /* 9 */ "mmmmmmmmt....t." - /* 10 */ "mmmmmmmmtv...t." - /* 11 */ "mmmmmmmmt...vt." - /* 12 */ "mmmmmmmmt....t." - /* 13 */ "mmmmmmmmis..si." - /* 14 */ "mmmmmmmmhittih." - /* 15 */ "mmmmmmmm......." + /* 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 */ "..............." - /* 1 */ ".hwwwwwwwwwwwh." - /* 2 */ ".x....y.y....x." - /* 3 */ ".x...........x." - /* 4 */ ".xz..........x." - /* 5 */ ".x...........x." - /* 6 */ ".x......A....x." - /* 7 */ "mhwwwwwwhz..Bx." - /* 8 */ "mmmmmmmmx....x." - /* 9 */ "mmmmmmmmx....x." - /* 10 */ "mmmmmmmmx....x." - /* 11 */ "mmmmmmmmx....x." - /* 12 */ "mmmmmmmmx....x." - /* 13 */ "mmmmmmmmx.AA.x." - /* 14 */ "mmmmmmmmhwwwwh." - /* 15 */ "mmmmmmmm......." + /* 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 */ "ppppppppppppppq" - /* 1 */ "riiiiiiiiiiiiiq" - /* 2 */ "riCCCCCCCCCCDiq" - /* 3 */ "riE.........Diq" - /* 4 */ "riE.........Diq" - /* 5 */ "riE.........Diq" - /* 6 */ "riEFFFFFFF..Diq" - /* 7 */ "riiiiiiiiE..Diq" - /* 8 */ "rnnnnnnriE..Diq" - /* 9 */ "mmmmmmmriE..Diq" - /* 10 */ "mmmmmmmriE..Diq" - /* 11 */ "mmmmmmmriE..Diq" - /* 12 */ "mmmmmmmriE..Diq" - /* 13 */ "mmmmmmmriEFFDiq" - /* 14 */ "mmmmmmmriiiiiiq" - /* 15 */ "mmmmmmmrnnnnnnn" + /* 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 */ "mmmmmmmmmmmmmmm" - /* 1 */ "mrpppppppppppqm" - /* 2 */ "mriiiiiiiiiiiqm" - /* 3 */ "mriiiiiiiiiiiqm" - /* 4 */ "mriiiiiiiiiiiqm" - /* 5 */ "mriiiiiiiiiiiqm" - /* 6 */ "mriiiiiiiiiiiqm" - /* 7 */ "mrnnnnnnniiiiqm" - /* 8 */ "mmmmmmmmriiiiqm" - /* 9 */ "mmmmmmmmriiiiqm" - /* 10 */ "mmmmmmmmriiiiqm" - /* 11 */ "mmmmmmmmriiiiqm" - /* 12 */ "mmmmmmmmriiiiqm" - /* 13 */ "mmmmmmmmriiiiqm" - /* 14 */ "mmmmmmmmnnnnnqm" - /* 15 */ "mmmmmmmmmmmmmmm" + /* 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 */ "mmmmmmmmmmmmmmm" - /* 1 */ "mmmmmmmmmmmmmmm" - /* 2 */ "mmpppppppppppmm" - /* 3 */ "mmriiiiiiiiiqmm" - /* 4 */ "mmriiiiiiiiiqmm" - /* 5 */ "mmriiiiiiiiiqmm" - /* 6 */ "mmnnnnnnnniiqmm" - /* 7 */ "mmmmmmmmmriiqmm" - /* 8 */ "mmmmmmmmmriiqmm" - /* 9 */ "mmmmmmmmmriiqmm" - /* 10 */ "mmmmmmmmmriiqmm" - /* 11 */ "mmmmmmmmmriiqmm" - /* 12 */ "mmmmmmmmmriiqmm" - /* 13 */ "mmmmmmmmmnnnqmm" - /* 14 */ "mmmmmmmmmmmmmmm" - /* 15 */ "mmmmmmmmmmmmmmm" - - // Level 9 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "mmmmmmmmmmmmmmm" - /* 1 */ "mmmmmmmmmmmmmmm" - /* 2 */ "mmmmmmmmmmmmmmm" - /* 3 */ "mmmrpppppppqmmm" - /* 4 */ "mmmriiiiiiiqmmm" - /* 5 */ "mmmrnnnnnnrqmmm" - /* 6 */ "mmmmmmmmmmrqmmm" - /* 7 */ "mmmmmmmmmmrqmmm" - /* 8 */ "mmmmmmmmmmrqmmm" - /* 9 */ "mmmmmmmmmmrqmmm" - /* 10 */ "mmmmmmmmmmrqmmm" - /* 11 */ "mmmmmmmmmmrqmmm" - /* 12 */ "mmmmmmmmmmrnmmm" - /* 13 */ "mmmmmmmmmmmmmmm" - /* 14 */ "mmmmmmmmmmmmmmm" - /* 15 */ "mmmmmmmmmmmmmmm", + /* 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, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 7, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -2864,6 +3383,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouseL13x14 @@ -2873,182 +3395,203 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 0, ID 4, created by Aloe_vera { // Size: - 16, 7, 16, // SizeX = 16, SizeY = 7, SizeZ = 16 + 16, 8, 16, // SizeX = 16, SizeY = 8, SizeZ = 16 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 16, 6, 16, // MaxX, MaxY, MaxZ + -1, 1, 0, // MinX, MinY, MinZ + 16, 7, 16, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 67: 0\n" /* stairs */ - "b: 67: 2\n" /* stairs */ - "c: 67: 1\n" /* stairs */ - "d: 4: 0\n" /* cobblestone */ - "e: 5: 0\n" /* wood */ - "f: 67: 3\n" /* stairs */ - "g: 17: 0\n" /* tree */ - "h: 64: 7\n" /* wooddoorblock */ - "i: 64: 5\n" /* wooddoorblock */ - "j:102: 0\n" /* glasspane */ - "k: 64:12\n" /* wooddoorblock */ - "l: 53: 2\n" /* woodstairs */ + "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: 1\n" /* woodstairs */ - "o: 53: 7\n" /* woodstairs */ - "p: 53: 6\n" /* woodstairs */ - "q: 53: 3\n" /* woodstairs */ - "r: 53: 0\n" /* woodstairs */ - "s: 53: 5\n" /* woodstairs */ - "t: 53: 4\n" /* woodstairs */ - "u: 50: 3\n" /* torch */ - "v: 50: 2\n" /* torch */ - "w: 50: 4\n" /* torch */ - "x: 50: 1\n" /* torch */, + "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 */ "........abc....." - /* 1 */ ".dddddddddddddd." - /* 2 */ ".deeeeeeeeeeeed." - /* 3 */ ".deeeeeeeeeeeed." - /* 4 */ ".deeeeeeeeeeeed." - /* 5 */ ".deeeeeeeeeeeed." - /* 6 */ ".deeeeeeeeeeeed." - /* 7 */ ".ddddddddeeeeed." - /* 8 */ "mmmmmafcdeeeeed." - /* 9 */ "mmmmmmmmdeeeeed." - /* 10 */ "mmmmmmmmdeeeeed." - /* 11 */ "mmmmmmmmdeeeeed." - /* 12 */ "mmmmmmmmdeeeeed." - /* 13 */ "mmmmmmmmdeeeeed." - /* 14 */ "mmmmmmmmddddddd." - /* 15 */ "mmmmmmmm........" + /* 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 */ "................" - /* 1 */ ".geeeeeeghgeeeg." - /* 2 */ ".e............e." - /* 3 */ ".e............e." - /* 4 */ ".e............e." - /* 5 */ ".e............e." - /* 6 */ ".e............e." - /* 7 */ ".geeeeieg.....e." - /* 8 */ "mmmmmm.me.....e." - /* 9 */ "mmmmmmmme.....e." - /* 10 */ "mmmmmmmme.....e." - /* 11 */ "mmmmmmmme.....e." - /* 12 */ "mmmmmmmme.....e." - /* 13 */ "mmmmmmmme.....e." - /* 14 */ "mmmmmmmmgeeeeeg." - /* 15 */ "mmmmmmmm........" + /* 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 */ ".gejjejjgkgjjeg." - /* 2 */ ".j............e." - /* 3 */ ".j............j." - /* 4 */ ".j............j." - /* 5 */ ".j............e." - /* 6 */ ".j............j." - /* 7 */ ".gejjekeg.....j." - /* 8 */ "mmmmmm.me.....e." - /* 9 */ "mmmmmmmmj.....j." - /* 10 */ "mmmmmmmmj.....j." - /* 11 */ "mmmmmmmme.....e." - /* 12 */ "mmmmmmmmj.....j." - /* 13 */ "mmmmmmmmj.....j." - /* 14 */ "mmmmmmmmgjjjjjg." - /* 15 */ "mmmmmmmm........" + /* 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 */ "llllllllllllllln" - /* 1 */ "ogeeeeeegegeeegn" - /* 2 */ ".e............en" - /* 3 */ ".e............en" - /* 4 */ ".e............en" - /* 5 */ ".e............en" - /* 6 */ ".e............en" - /* 7 */ "pgeeeeeeg.....en" - /* 8 */ "qqqqqqqre.....en" - /* 9 */ "mmmmmmmre.....en" - /* 10 */ "mmmmmmmre.....en" - /* 11 */ "mmmmmmmre.....en" - /* 12 */ "mmmmmmmre.....en" - /* 13 */ "mmmmmmmre.....en" - /* 14 */ "mmmmmmmrgeeeeegn" - /* 15 */ "mmmmmmmrs.....tn" + /* 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 */ "................" - /* 1 */ "lllllllllllllll." - /* 2 */ "oeeeeeeeeeeeeen." - /* 3 */ ".e.........u.en." - /* 4 */ ".e..........ven." - /* 5 */ ".e......w....en." - /* 6 */ "peeeeeeeee...en." - /* 7 */ "qqqqqqqqrex..en." - /* 8 */ "mmmmmmmmre...en." - /* 9 */ "mmmmmmmmre...en." - /* 10 */ "mmmmmmmmre...en." - /* 11 */ "mmmmmmmmre...en." - /* 12 */ "mmmmmmmmre...en." - /* 13 */ "mmmmmmmmre...en." - /* 14 */ "mmmmmmmmreeeeen." - /* 15 */ "mmmmmmmmrs...tn." + /* 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 */ "................" - /* 2 */ "llllllllllllln.." - /* 3 */ "oeeeeeeeeeeeen.." - /* 4 */ ".ex.........en.." - /* 5 */ "peeeeeeeeee.en.." - /* 6 */ "qqqqqqqqqre.en.." - /* 7 */ ".........re.en.." - /* 8 */ "mmmmmmmm.re.en.." - /* 9 */ "mmmmmmmm.re.en.." - /* 10 */ "mmmmmmmm.re.en.." - /* 11 */ "mmmmmmmm.re.en.." - /* 12 */ "mmmmmmmm.re.en.." - /* 13 */ "mmmmmmmm.rewen.." - /* 14 */ "mmmmmmmm.reeen.." - /* 15 */ "mmmmmmmm.rs.tn.." + /* 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 */ "lllllllllllll..." - /* 4 */ "eeeeeeeeeeeen..." - /* 5 */ "qqqqqqqqqqren..." - /* 6 */ "..........ren..." - /* 7 */ "..........ren..." - /* 8 */ "mmmmmmmm..ren..." - /* 9 */ "mmmmmmmm..ren..." - /* 10 */ "mmmmmmmm..ren..." - /* 11 */ "mmmmmmmm..ren..." - /* 12 */ "mmmmmmmm..ren..." - /* 13 */ "mmmmmmmm..ren..." - /* 14 */ "mmmmmmmm..ren..." - /* 15 */ "mmmmmmmm..ren...", + /* 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, 0, 0: 2\n" /* Type -1, direction Z- */, + "-1: 9, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -3067,6 +3610,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouseL14x14 @@ -3076,162 +3622,145 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 42, ID 93, created by xoft { // Size: - 11, 8, 11, // SizeX = 11, SizeY = 8, SizeZ = 11 + 11, 7, 11, // SizeX = 11, SizeY = 7, SizeZ = 11 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 11, 7, 11, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 11, 6, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j:102: 0\n" /* glasspane */ - "k: 64:12\n" /* wooddoorblock */ - "l: 53: 2\n" /* woodstairs */ + "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: 53: 7\n" /* woodstairs */ - "o: 53: 1\n" /* woodstairs */ - "p: 50: 3\n" /* torch */ - "q: 50: 4\n" /* torch */ - "r: 53: 6\n" /* woodstairs */ - "s: 50: 1\n" /* torch */ - "t: 50: 2\n" /* torch */ - "u: 53: 3\n" /* woodstairs */ - "v: 53: 0\n" /* woodstairs */ - "w: 53: 5\n" /* woodstairs */ - "x: 53: 4\n" /* woodstairs */, + "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 */ "aaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaa" - /* 7 */ "aaaaaaaaaaa" - /* 8 */ "aaaaaaaaaaa" - /* 9 */ "aaaaaaaaaaa" - /* 10 */ "aaaaaaaaaaa" + /* 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 */ "bbbbaaabbbb" - /* 1 */ "baaaaaaaaab" - /* 2 */ "baaaaaaaaab" - /* 3 */ "baaaaaaaaab" - /* 4 */ "baaaaaaaaab" - /* 5 */ "baaaaaaaaab" - /* 6 */ "bbbbbaaaaab" - /* 7 */ "bbbbbaaaaab" - /* 8 */ "bbbbbaaaaab" - /* 9 */ "bbbbbaaaaab" - /* 10 */ "bbbbbbbbbbb" + /* 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 */ "....cde...." - /* 1 */ ".fffffffff." - /* 2 */ ".fffffffff." - /* 3 */ ".fffffffff." - /* 4 */ ".fffffffff." - /* 5 */ ".fffffffff." - /* 6 */ ".....fffff." - /* 7 */ "mmmm.fffff." - /* 8 */ "mmmm.fffff." - /* 9 */ "mmmm.fffff." - /* 10 */ "mmmm......." + /* 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 */ ".ghhhihhhg." + /* 1 */ ".ehhfifhhe." /* 2 */ ".h.......h." /* 3 */ ".h.......h." /* 4 */ ".h.......h." - /* 5 */ ".ghhhg...h." + /* 5 */ ".ehhhe...f." /* 6 */ ".....h...h." - /* 7 */ "mmmm.h...h." - /* 8 */ "mmmm.h...h." - /* 9 */ "mmmm.ghhhg." - /* 10 */ "mmmm......." + /* 7 */ ".....h...h." + /* 8 */ ".....h...h." + /* 9 */ ".....ehhhe." + /* 10 */ "..........." // Level 4 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "..........." - /* 1 */ ".gjjhkhjjg." - /* 2 */ ".j.......j." - /* 3 */ ".j.......j." - /* 4 */ ".j.......j." - /* 5 */ ".gjjjg...h." - /* 6 */ ".....j...j." - /* 7 */ "mmmm.j...j." - /* 8 */ "mmmm.j...j." - /* 9 */ "mmmm.gjjjg." - /* 10 */ "mmmm......." + /* 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 */ "lllllllllll" - /* 1 */ "nhhhhhhhhho" - /* 2 */ ".h..p.p..ho" - /* 3 */ ".h.......ho" - /* 4 */ ".h...q...ho" - /* 5 */ "rhhhhhs.tho" - /* 6 */ "uuuuuh...ho" - /* 7 */ "mmmmvh...ho" - /* 8 */ "mmmmvh...ho" - /* 9 */ "mmmmvhhhhho" - /* 10 */ "mmmmvw...xo" + /* 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 */ "lllllllllo." - /* 2 */ "nhhhhhhhho." - /* 3 */ ".h......ho." - /* 4 */ "rhhhhhh.ho." - /* 5 */ "uuuuuuh.ho." - /* 6 */ ".....vh.ho." - /* 7 */ "mmmm.vh.ho." - /* 8 */ "mmmm.vh.ho." - /* 9 */ "mmmm.vhhho." - /* 10 */ "mmmm.vw.xo." - - // Level 7 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "..........." /* 1 */ "..........." - /* 2 */ "lllllllll.." - /* 3 */ "hhhhhhhho.." - /* 4 */ "uuuuuuvho.." - /* 5 */ "......vho.." - /* 6 */ "......vho.." - /* 7 */ "mmmm..vho.." - /* 8 */ "mmmm..vho.." - /* 9 */ "mmmm..vho.." - /* 10 */ "mmmm..vho..", + /* 2 */ "jjjjjjjjj.." + /* 3 */ "ffffffffl.." + /* 4 */ "sssssstfl.." + /* 5 */ "......tfl.." + /* 6 */ "......tfl.." + /* 7 */ "......tfl.." + /* 8 */ "......tfl.." + /* 9 */ "......tfl.." + /* 10 */ "......tfl..", // Connectors: - "-1: 5, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -3250,6 +3779,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouseL9x9 @@ -3259,160 +3791,143 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 43, ID 94, created by xoft { // Size: - 15, 8, 11, // SizeX = 15, SizeY = 8, SizeZ = 11 + 15, 7, 11, // SizeX = 15, SizeY = 7, SizeZ = 11 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 15, 7, 11, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 15, 6, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 64: 7\n" /* wooddoorblock */ - "j:102: 0\n" /* glasspane */ - "k: 64:12\n" /* wooddoorblock */ - "l: 53: 2\n" /* woodstairs */ + "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: 53: 0\n" /* woodstairs */ - "o: 53: 1\n" /* woodstairs */ - "p: 50: 3\n" /* torch */ - "q: 50: 4\n" /* torch */ - "r: 50: 2\n" /* torch */ - "s: 50: 1\n" /* torch */ - "t: 53: 3\n" /* woodstairs */ - "u: 53: 5\n" /* woodstairs */ - "v: 53: 4\n" /* woodstairs */, + "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 */ "aaaaaaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaaaaaa" - /* 7 */ "aaaaaaaaaaaaaaa" - /* 8 */ "aaaaaaaaaaaaaaa" - /* 9 */ "aaaaaaaaaaaaaaa" - /* 10 */ "aaaaaaaaaaaaaaa" + /* 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 */ "bbbbbbaaabbbbbb" - /* 1 */ "baaaaaaaaaaaaab" - /* 2 */ "baaaaaaaaaaaaab" - /* 3 */ "baaaaaaaaaaaaab" - /* 4 */ "baaaaaaaaaaaaab" - /* 5 */ "baaaaaaaaaaaaab" - /* 6 */ "baaaaabbbaaaaab" - /* 7 */ "baaaaabbbaaaaab" - /* 8 */ "baaaaabbbaaaaab" - /* 9 */ "baaaaabbbaaaaab" - /* 10 */ "bbbbbbbbbbbbbbb" + /* 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 */ "......cde......" - /* 1 */ ".fffffffffffff." - /* 2 */ ".fffffffffffff." - /* 3 */ ".fffffffffffff." - /* 4 */ ".fffffffffffff." - /* 5 */ ".fffffffffffff." - /* 6 */ ".fffff...fffff." - /* 7 */ ".fffff...fffff." - /* 8 */ ".fffff...fffff." - /* 9 */ ".fffff...fffff." + /* 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 */ ".ghhhhhihhhhhg." + /* 1 */ ".ehhhhfifhhhhe." /* 2 */ ".h...........h." /* 3 */ ".h...........h." /* 4 */ ".h...........h." - /* 5 */ ".h...ghhhg...h." + /* 5 */ ".f...ehhhe...f." /* 6 */ ".h...h...h...h." /* 7 */ ".h...h...h...h." /* 8 */ ".h...h...h...h." - /* 9 */ ".ghhhg...ghhhg." + /* 9 */ ".ehhhe...ehhhe." /* 10 */ "..............." // Level 4 /* z\x* 11111 */ /* * 012345678901234 */ - /* 0 */ "..............." - /* 1 */ ".gjjjjhkhjjjjg." - /* 2 */ ".j...........j." - /* 3 */ ".j...........j." - /* 4 */ ".j...........j." - /* 5 */ ".h...gjjjg...h." - /* 6 */ ".j...j...j...j." - /* 7 */ ".j...j...j...j." - /* 8 */ ".j...j...j...j." - /* 9 */ ".gjjjg...gjjjg." - /* 10 */ "..............." + /* 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 */ "lllllllllllllll" - /* 1 */ "nhhhhhhhhhhhhho" - /* 2 */ "nh....p.p....ho" - /* 3 */ "nh...........ho" - /* 4 */ "nh...q...q...ho" - /* 5 */ "nh..rhhhhhs..ho" - /* 6 */ "nh...httth...ho" - /* 7 */ "nh...ho.nh...ho" - /* 8 */ "nh...ho.nh...ho" - /* 9 */ "nhhhhho.nhhhhho" - /* 10 */ "nu...vo.nu...vo" + /* 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 */ ".llllllllllllo." - /* 2 */ ".nhhhhhhhhhhho." - /* 3 */ ".nhhhhhhhhhhho." - /* 4 */ ".nhhhhhhhhhhho." - /* 5 */ ".nhhhotttthhho." - /* 6 */ ".nhhho...nhhho." - /* 7 */ ".nhhho...nhhho." - /* 8 */ ".nhhho...nhhho." - /* 9 */ ".nhhho...nhhho." - /* 10 */ ".nu.vo...nu.vo." - - // Level 7 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "..............." /* 1 */ "..............." - /* 2 */ "..nllllllllll.." - /* 3 */ "..nhhhhhhhhho.." - /* 4 */ "..nhotttttnho.." - /* 5 */ "..nho.....nho.." - /* 6 */ "..nho.....nho.." - /* 7 */ "..nho.....nho.." - /* 8 */ "..nho.....nho.." - /* 9 */ "..nho.....nho.." - /* 10 */ "..nho.....nho..", + /* 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, 2, 0: 2\n" /* Type -1, direction Z- */, + "-1: 7, 1, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -3431,6 +3946,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenHouseU13x9 @@ -3440,262 +3958,260 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 60, ID 111, created by Aloe_vera { // Size: - 9, 18, 13, // SizeX = 9, SizeY = 18, SizeZ = 13 + 9, 17, 13, // SizeX = 9, SizeY = 17, SizeZ = 13 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 8, 17, 12, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 8, 16, 12, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 4: 0\n" /* cobblestone */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 67: 3\n" /* stairs */ - "g: 17: 0\n" /* tree */ - "h: 5: 0\n" /* wood */ - "i: 54: 4\n" /* chest */ - "j:154: 4\n" /* hopper */ - "k: 64: 4\n" /* wooddoorblock */ - "l:102: 0\n" /* glasspane */ + "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: 85: 0\n" /* fence */ - "o: 64:12\n" /* wooddoorblock */ - "p: 50: 2\n" /* torch */ - "q: 35: 0\n" /* wool */ - "r: 17: 4\n" /* tree */ - "s: 17: 8\n" /* tree */ - "t: 53: 2\n" /* woodstairs */ - "u: 53: 7\n" /* woodstairs */ - "v: 53: 6\n" /* woodstairs */ - "w: 53: 3\n" /* woodstairs */, + "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 */ "aaaaaaaaa" - /* 1 */ "aaaaaaaaa" - /* 2 */ "aaaaaaaaa" - /* 3 */ "aaaaaaaaa" - /* 4 */ "aaaaaaaaa" - /* 5 */ "aaaaaaaaa" - /* 6 */ "aaaaaaaaa" - /* 7 */ "aaaaaaaaa" - /* 8 */ "aaaaaaaaa" - /* 9 */ "aaaaaaaaa" - /* 10 */ "aaaaaaaaa" - /* 11 */ "aaaaaaaaa" - /* 12 */ "aaaaaaaaa" + /* 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 */ "bbbbbbbbb" - /* 1 */ "bbbbbbbbb" - /* 2 */ "bbbbbbbbb" - /* 3 */ "bbbbbbbbb" - /* 4 */ "baaaaabbb" - /* 5 */ "baaaaaabb" - /* 6 */ "baaaaaabb" - /* 7 */ "baaaaaabb" - /* 8 */ "baaaaabbb" - /* 9 */ "bbbbbbbbb" - /* 10 */ "bbbbbbbbb" - /* 11 */ "bbbbbbbbb" - /* 12 */ "bbbbbbbbb" + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." + /* 3 */ "........." + /* 4 */ ".aaaaa..." + /* 5 */ ".aaaaab.." + /* 6 */ ".aaaaac.." + /* 7 */ ".aaaaad.." + /* 8 */ ".aaaaa..." + /* 9 */ "........." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 2 /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." /* 3 */ "........." - /* 4 */ ".ccccc..." - /* 5 */ ".cccccd.." - /* 6 */ ".ccccce.." - /* 7 */ ".cccccf.." - /* 8 */ ".ccccc..." + /* 4 */ ".efffe..." + /* 5 */ ".f...f..." + /* 6 */ ".fgh.i..." + /* 7 */ ".f...f..." + /* 8 */ ".efffe..." /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 3 /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." /* 3 */ "........." - /* 4 */ ".ghhhg..." - /* 5 */ ".h...h..." - /* 6 */ ".hij.k..." - /* 7 */ ".h...h..." - /* 8 */ ".ghhhg..." + /* 4 */ ".ejjje..." + /* 5 */ ".j...f..." + /* 6 */ ".j.k.l..." + /* 7 */ ".j...f..." + /* 8 */ ".ejjje..." /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 4 /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." /* 3 */ "........." - /* 4 */ ".glllg..." - /* 5 */ ".l...h..." - /* 6 */ ".l.n.o..." - /* 7 */ ".l...h..." - /* 8 */ ".glllg..." + /* 4 */ ".efffe..." + /* 5 */ ".f..nf..." + /* 6 */ ".f.k.f..." + /* 7 */ ".f..nf..k" + /* 8 */ ".efffe..o" /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 5 /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." /* 3 */ "........." - /* 4 */ ".ghhhg..." - /* 5 */ ".h..ph..." - /* 6 */ ".h.n.h..." - /* 7 */ ".h..ph..n" - /* 8 */ ".ghhhg..q" + /* 4 */ ".epppe..." + /* 5 */ ".q...q..." + /* 6 */ ".q.k.q..." + /* 7 */ ".q...q..k" + /* 8 */ ".epppe..o" /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 6 /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." /* 3 */ "........." - /* 4 */ ".grrrg..." - /* 5 */ ".s...s..." - /* 6 */ ".s.n.s..." - /* 7 */ ".s...s..n" - /* 8 */ ".grrrg..q" + /* 4 */ ".efffe..." + /* 5 */ ".f...f..." + /* 6 */ ".f.k.f..k" + /* 7 */ ".f...f..o" + /* 8 */ ".efffe..o" /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 7 /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." /* 3 */ "........." - /* 4 */ ".ghhhg..." - /* 5 */ ".h...h..." - /* 6 */ ".h.n.h..n" - /* 7 */ ".h...h..q" - /* 8 */ ".ghhhg..q" + /* 4 */ ".ejjje..." + /* 5 */ ".j...j..." + /* 6 */ ".j.k.j..k" + /* 7 */ ".j...j..o" + /* 8 */ ".ejjje..." /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 8 /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." + /* 0 */ "........o" + /* 1 */ "........o" + /* 2 */ "........o" /* 3 */ "........." - /* 4 */ ".glllg..." - /* 5 */ ".l...l..." - /* 6 */ ".l.n.l..n" - /* 7 */ ".l...l..q" - /* 8 */ ".glllg..." + /* 4 */ ".efffe..." + /* 5 */ ".f...f..k" + /* 6 */ ".f.k.f..o" + /* 7 */ ".f...f..o" + /* 8 */ ".efffe..." /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 9 /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.q" - /* 1 */ "mmmmmmm.q" - /* 2 */ "mmmmmmm.q" - /* 3 */ "........." - /* 4 */ ".ghhhg..." - /* 5 */ ".h...h..n" - /* 6 */ ".h.n.h..q" - /* 7 */ ".h...h..q" - /* 8 */ ".ghhhg..." + /* 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 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 10 /* z\x* 012345678 */ - /* 0 */ "mmmmmmm.n" - /* 1 */ "mmmmmmm.n" - /* 2 */ "mmmmmmm.q" - /* 3 */ "........q" - /* 4 */ ".grrrg..q" - /* 5 */ ".s...s..n" - /* 6 */ ".s.n.s..q" - /* 7 */ ".s...s..n" - /* 8 */ ".grrrg..n" - /* 9 */ "........." - /* 10 */ "mmmmmmm.." - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 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 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.n" - /* 3 */ "ttttttt.n" - /* 4 */ "uhhhhhu.q" - /* 5 */ ".h...h..q" - /* 6 */ ".h.nrrrrr" - /* 7 */ ".h...h..q" - /* 8 */ "vhhhhhv.q" - /* 9 */ "wwwwwww.n" - /* 10 */ "mmmmmmm.n" - /* 11 */ "mmmmmmm.." - /* 12 */ "mmmmmmm.." + /* 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 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "mmmmmmm.." - /* 4 */ "ttttttt.n" - /* 5 */ "uhhhhhu.n" - /* 6 */ ".h...h..q" - /* 7 */ "vhhhhhv.n" - /* 8 */ "wwwwwww.q" - /* 9 */ "mmmmmmm.q" - /* 10 */ "mmmmmmm.q" - /* 11 */ "mmmmmmm.n" - /* 12 */ "mmmmmmm.n" + /* 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 */ "mmmmmmm.." - /* 1 */ "mmmmmmm.." - /* 2 */ "mmmmmmm.." - /* 3 */ "mmmmmmm.." - /* 4 */ "mmmmmmm.." - /* 5 */ "ttttttt.q" - /* 6 */ "hhhhhhh.q" - /* 7 */ "wwwwwww.n" - /* 8 */ "mmmmmmm.." - /* 9 */ "mmmmmmm.." - /* 10 */ "mmmmmmm.q" - /* 11 */ "mmmmmmm.q" - /* 12 */ "mmmmmmm.q" + /* 0 */ "........." + /* 1 */ "........." + /* 2 */ "........." + /* 3 */ "........." + /* 4 */ "........." + /* 5 */ "........o" + /* 6 */ "........k" + /* 7 */ "........." + /* 8 */ "........." + /* 9 */ "........." + /* 10 */ "........." + /* 11 */ "........." + /* 12 */ "........." // Level 14 /* z\x* 012345678 */ @@ -3703,9 +4219,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 1 */ "........." /* 2 */ "........." /* 3 */ "........." - /* 4 */ "........." - /* 5 */ "........q" - /* 6 */ "........n" + /* 4 */ "........o" + /* 5 */ "........o" + /* 6 */ "........k" /* 7 */ "........." /* 8 */ "........." /* 9 */ "........." @@ -3719,9 +4235,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 1 */ "........." /* 2 */ "........." /* 3 */ "........." - /* 4 */ "........q" - /* 5 */ "........q" - /* 6 */ "........n" + /* 4 */ "........o" + /* 5 */ "........k" + /* 6 */ "........." /* 7 */ "........." /* 8 */ "........." /* 9 */ "........." @@ -3735,24 +4251,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 1 */ "........." /* 2 */ "........." /* 3 */ "........." - /* 4 */ "........q" - /* 5 */ "........n" - /* 6 */ "........." - /* 7 */ "........." - /* 8 */ "........." - /* 9 */ "........." - /* 10 */ "........." - /* 11 */ "........." - /* 12 */ "........." - - // Level 17 - /* z\x* 012345678 */ - /* 0 */ "........." - /* 1 */ "........." - /* 2 */ "........." - /* 3 */ "........." - /* 4 */ "........q" - /* 5 */ "........n" + /* 4 */ "........o" + /* 5 */ "........k" /* 6 */ "........." /* 7 */ "........." /* 8 */ "........." @@ -3762,7 +4262,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 12 */ ".........", // Connectors: - "-1: 8, 2, 6: 5\n" /* Type -1, direction X+ */, + "-1: 8, 1, 6: 5\n" /* Type -1, direction X+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -3781,6 +4281,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenMill5x5 @@ -3790,140 +4293,139 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 55, ID 106, created by Aloe_vera { // Size: - 15, 10, 9, // SizeX = 15, SizeY = 10, SizeZ = 9 + 15, 9, 9, // SizeX = 15, SizeY = 9, SizeZ = 9 // Hitbox (relative to bounding box): - -1, 0, 0, // MinX, MinY, MinZ - 15, 9, 9, // MaxX, MaxY, MaxZ + -1, -1, 0, // MinX, MinY, MinZ + 15, 8, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ - "c: 67: 0\n" /* stairs */ - "d: 67: 2\n" /* stairs */ - "e: 67: 1\n" /* stairs */ - "f: 4: 0\n" /* cobblestone */ - "g: 17: 0\n" /* tree */ - "h:107: 0\n" /* fencegate */ - "i:107: 4\n" /* fencegate */ - "j: 5: 0\n" /* wood */ - "k:107: 6\n" /* fencegate */ - "l: 85: 0\n" /* fence */ + "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: 0\n" /* haybale */ - "o:170: 4\n" /* haybale */ - "p:170: 8\n" /* haybale */ - "q: 50: 1\n" /* torch */ - "r: 50: 2\n" /* torch */ - "s: 53: 2\n" /* woodstairs */ - "t: 53: 7\n" /* woodstairs */ - "u: 53: 6\n" /* woodstairs */ - "v: 53: 3\n" /* woodstairs */, + "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 */ "aaaaaaaaaaaaaaa" - /* 1 */ "aaaaaaaaaaaaaaa" - /* 2 */ "aaaaaaaaaaaaaaa" - /* 3 */ "aaaaaaaaaaaaaaa" - /* 4 */ "aaaaaaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaaaaaa" - /* 7 */ "aaaaaaaaaaaaaaa" - /* 8 */ "aaaaaaaaaaaaaaa" + /* 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 */ "baaaaaaaaaaaaab" - /* 1 */ "baaaaaaaaaaaaab" - /* 2 */ "baaaaaaaaaaaaab" - /* 3 */ "baaaaaaaaaaaaab" - /* 4 */ "baaaaaaaaaaaaab" - /* 5 */ "baaaaaaaaaaaaab" - /* 6 */ "baaaaaaaaaaaaab" - /* 7 */ "baaaaaaaaaaaaab" - /* 8 */ "bbbbbbbbbbbbbbb" + /* 0 */ ".bcccccccccccd." + /* 1 */ ".aaaaaaaaaaaaa." + /* 2 */ ".aeeeeeeeeeeea." + /* 3 */ ".aeeeeeeeeeeea." + /* 4 */ ".aeeeeeeeeeeea." + /* 5 */ ".aeeeeeeeeeeea." + /* 6 */ ".aeeeeeeeeeeea." + /* 7 */ ".aaaaaaaaaaaaa." + /* 8 */ "..............." // Level 2 /* z\x* 11111 */ /* * 012345678901234 */ - /* 0 */ ".cddddddddddde." - /* 1 */ ".fffffffffffff." - /* 2 */ ".faaaaaaaaaaaf." - /* 3 */ ".faaaaaaaaaaaf." - /* 4 */ ".faaaaaaaaaaaf." - /* 5 */ ".faaaaaaaaaaaf." - /* 6 */ ".faaaaaaaaaaaf." - /* 7 */ ".fffffffffffff." + /* 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 */ ".ghihjhihjhkhg." - /* 2 */ ".l...l...l...l." - /* 3 */ ".l...l...l...l." - /* 4 */ ".l...l...l...l." - /* 5 */ ".l...l...l...l." - /* 6 */ ".ln..l..olp..l." - /* 7 */ ".gllljllljlllg." + /* 1 */ ".f...i...i...f." + /* 2 */ "..............." + /* 3 */ "..............." + /* 4 */ "..............." + /* 5 */ "..............." + /* 6 */ "..............." + /* 7 */ ".f...i...i...f." /* 8 */ "..............." // Level 4 /* z\x* 11111 */ /* * 012345678901234 */ /* 0 */ "..............." - /* 1 */ ".g...j...j...g." + /* 1 */ ".fp.qip.qip.qf." /* 2 */ "..............." /* 3 */ "..............." /* 4 */ "..............." /* 5 */ "..............." /* 6 */ "..............." - /* 7 */ ".g...j...j...g." + /* 7 */ ".f...i...i...f." /* 8 */ "..............." // Level 5 /* z\x* 11111 */ /* * 012345678901234 */ - /* 0 */ "..............." - /* 1 */ ".gq.rjq.rjq.rg." - /* 2 */ "..............." - /* 3 */ "..............." - /* 4 */ "..............." - /* 5 */ "..............." - /* 6 */ "..............." - /* 7 */ ".g...j...j...g." - /* 8 */ "..............." + /* 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 */ "sssssssssssssss" - /* 1 */ "tjjjjjjjjjjjjjt" - /* 2 */ ".j...........j." - /* 3 */ ".j...........j." - /* 4 */ ".j...........j." - /* 5 */ ".j...........j." - /* 6 */ ".j...........j." - /* 7 */ "ujjjjjjjjjjjjju" - /* 8 */ "vvvvvvvvvvvvvvv" + /* 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 */ "sssssssssssssss" - /* 2 */ "tjjjjjjjjjjjjjt" - /* 3 */ ".j...........j." - /* 4 */ ".j...........j." - /* 5 */ ".j...........j." - /* 6 */ "ujjjjjjjjjjjjju" - /* 7 */ "vvvvvvvvvvvvvvv" + /* 1 */ "..............." + /* 2 */ "rrrrrrrrrrrrrrr" + /* 3 */ "siiiiiiiiiiiiis" + /* 4 */ ".i...........i." + /* 5 */ "tiiiiiiiiiiiiit" + /* 6 */ "uuuuuuuuuuuuuuu" + /* 7 */ "..............." /* 8 */ "..............." // Level 8 @@ -3931,29 +4433,16 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* * 012345678901234 */ /* 0 */ "..............." /* 1 */ "..............." - /* 2 */ "sssssssssssssss" - /* 3 */ "tjjjjjjjjjjjjjt" - /* 4 */ ".j...........j." - /* 5 */ "ujjjjjjjjjjjjju" - /* 6 */ "vvvvvvvvvvvvvvv" - /* 7 */ "..............." - /* 8 */ "..............." - - // Level 9 - /* z\x* 11111 */ - /* * 012345678901234 */ - /* 0 */ "..............." - /* 1 */ "..............." /* 2 */ "..............." - /* 3 */ "sssssssssssssss" - /* 4 */ "jjjjjjjjjjjjjjj" - /* 5 */ "vvvvvvvvvvvvvvv" + /* 3 */ "rrrrrrrrrrrrrrr" + /* 4 */ "iiiiiiiiiiiiiii" + /* 5 */ "uuuuuuuuuuuuuuu" /* 6 */ "..............." /* 7 */ "..............." /* 8 */ "...............", // Connectors: - "-1: 7, 2, -1: 2\n" /* Type -1, direction Z- */, + "-1: 7, 1, -1: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -3972,6 +4461,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // WoodenStables }; // g_PlainsVillagePrefabs @@ -4109,17 +4601,467 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] = true, // DefaultWeight: - 100, + 0, // 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: + 1000, + + // 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 @@ -4317,13 +5259,16 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] = true, // DefaultWeight: - 100, + 0, // DepthWeight: "", // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // RoofedWell }; diff --git a/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp index 93aa405c2..4f0efdcc6 100644 --- a/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp +++ b/src/Generating/Prefabs/SandFlatRoofVillagePrefabs.cpp @@ -141,6 +141,9 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // Forge @@ -264,6 +267,9 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House11x7 @@ -363,6 +369,9 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House5x4 @@ -468,6 +477,9 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House5x5 @@ -573,6 +585,9 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House7x5 @@ -683,6 +698,9 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House8x5 @@ -805,6 +823,9 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House8x7 @@ -928,6 +949,9 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House9x7 @@ -1078,6 +1102,9 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // HouseL13x12 @@ -1087,75 +1114,86 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = // The data has been exported from the gallery Desert, area index 34, ID 175, created by Aloe_vera { // Size: - 7, 5, 7, // SizeX = 7, SizeY = 5, SizeZ = 7 + 7, 6, 7, // SizeX = 7, SizeY = 6, SizeZ = 7 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 6, 4, 6, // MaxX, MaxY, MaxZ + 6, 5, 6, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "a: 85: 0\n" /* fence */ - "b:171:14\n" /* carpet */ - "c:171:15\n" /* carpet */ - "d:171: 0\n" /* carpet */ - "e: 35:14\n" /* wool */ - "f: 35: 0\n" /* wool */ + "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 */ "a.....a" - /* 1 */ "bccdccb" - /* 2 */ "bcdddcb" - /* 3 */ "bcdddcb" - /* 4 */ "bccdccb" - /* 5 */ "a.....a" - /* 6 */ "......." + /* 0 */ "aaaaaaa" + /* 1 */ "aaaaaaa" + /* 2 */ "aaaaaaa" + /* 3 */ "aaaaaaa" + /* 4 */ "aaaaaaa" + /* 5 */ "aaaaaaa" + /* 6 */ "aaaaaaa" // Level 1 /* z\x* 0123456 */ - /* 0 */ "a.....a" - /* 1 */ "......." - /* 2 */ "......." - /* 3 */ "......." - /* 4 */ "......." - /* 5 */ "a.....a" + /* 0 */ "b.....b" + /* 1 */ "cddeddc" + /* 2 */ "cdeeedc" + /* 3 */ "cdeeedc" + /* 4 */ "cddeddc" + /* 5 */ "b.....b" /* 6 */ "......." // Level 2 /* z\x* 0123456 */ - /* 0 */ "a.....a" + /* 0 */ "b.....b" /* 1 */ "......." /* 2 */ "......." /* 3 */ "......." /* 4 */ "......." - /* 5 */ "a.....a" - /* 6 */ "efefefe" + /* 5 */ "b.....b" + /* 6 */ "......." // Level 3 /* z\x* 0123456 */ - /* 0 */ "efefefe" + /* 0 */ "b.....b" /* 1 */ "......." /* 2 */ "......." /* 3 */ "......." /* 4 */ "......." - /* 5 */ "efefefe" - /* 6 */ "......." + /* 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 */ "efefefe" - /* 2 */ "efefefe" - /* 3 */ "efefefe" - /* 4 */ "efefefe" + /* 1 */ "fgfgfgf" + /* 2 */ "fgfgfgf" + /* 3 */ "fgfgfgf" + /* 4 */ "fgfgfgf" /* 5 */ "......." /* 6 */ ".......", // Connectors: - "-1: 2, -1, 0: 2\n" /* Type -1, direction Z- */, + "-1: 2, 0, 0: 2\n" /* Type -1, direction Z- */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -1167,13 +1205,16 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = true, // DefaultWeight: - 100, + 5, // DepthWeight: "", // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // MarketStall @@ -1300,13 +1341,16 @@ const cPrefab::sDef g_SandFlatRoofVillagePrefabs[] = true, // DefaultWeight: - 100, + 20, // DepthWeight: "", // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // Marketplace }; // g_SandFlatRoofVillagePrefabs @@ -1496,6 +1540,9 @@ const cPrefab::sDef g_SandFlatRoofVillageStartingPrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // Well }; diff --git a/src/Generating/Prefabs/SandVillagePrefabs.cpp b/src/Generating/Prefabs/SandVillagePrefabs.cpp index 539f57b9d..a062f8cd4 100644 --- a/src/Generating/Prefabs/SandVillagePrefabs.cpp +++ b/src/Generating/Prefabs/SandVillagePrefabs.cpp @@ -82,6 +82,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // DoubleField @@ -202,6 +205,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House11x7 @@ -345,6 +351,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House11x9 @@ -463,6 +472,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House13x7 @@ -606,6 +618,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House13x9 @@ -749,6 +764,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House15x9 @@ -892,6 +910,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House16x9 @@ -1003,6 +1024,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House7x7 @@ -1115,6 +1139,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // House9x7 @@ -1251,159 +1278,10 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, - }, // House9x9 - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // 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: + // MoveToGround: true, - - // DefaultWeight: - 100, - - // DepthWeight: - "", - - // AddWeightIfSame: - 0, - }, // HouseL14x12 + }, // House9x9 @@ -1571,6 +1449,164 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // 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 @@ -1638,6 +1674,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // SingleField @@ -1731,6 +1770,9 @@ const cPrefab::sDef g_SandVillagePrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // SmallHut }; // g_SandVillagePrefabs @@ -1741,6 +1783,204 @@ const cPrefab::sDef 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 @@ -1875,6 +2115,9 @@ const cPrefab::sDef g_SandVillageStartingPrefabs[] = // AddWeightIfSame: 0, + + // MoveToGround: + true, }, // Well }; diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index 62822c33b..cb1f4fe0d 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -127,10 +127,23 @@ public: m_HeightGen(a_HeightGen), m_RoadBlock(a_RoadBlock) { + // Generate the pieces for this village; don't care about the Y coord: cBFSPieceGenerator pg(*this, a_Seed); - // Generate the pieces at very negative Y coords, so that we can later test - // Piece has negative Y coord -> hasn't been height-adjusted yet - pg.PlacePieces(a_OriginX, -1000, a_OriginZ, a_MaxRoadDepth + 1, m_Pieces); + 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); + } } protected: @@ -179,7 +192,7 @@ protected: DrawRoad(a_Chunk, **itr, HeightMap); continue; } - if ((*itr)->GetCoords().y < 0) + if (Prefab.ShouldMoveToGround() && !(*itr)->HasBeenMovedToGround()) { PlacePieceOnGround(**itr); } @@ -201,7 +214,7 @@ protected: cChunkDef::HeightMap HeightMap; m_HeightGen.GenHeightMap(ChunkX, ChunkZ, HeightMap); int TerrainHeight = cChunkDef::GetHeight(HeightMap, BlockX, BlockZ); - a_Piece.GetCoords().y += TerrainHeight - FirstConnector.m_Pos.y + 1; + a_Piece.MoveToGroundBy(TerrainHeight - FirstConnector.m_Pos.y + 1); } @@ -232,11 +245,13 @@ protected: 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, @@ -258,15 +273,35 @@ protected: return m_Prefabs.GetPieceWeight(a_PlacedPiece, a_ExistingConnector, 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[] + } } ; From c9c2a4f479474fe03acce598ba2687a0f4817083 Mon Sep 17 00:00:00 2001 From: JoannisO Date: Mon, 26 May 2014 08:44:16 +0200 Subject: [PATCH 128/312] Added Arrow- and FireCharge-Dispensing to DispenserEntity. --- src/BlockEntities/DispenserEntity.cpp | 107 +++++++++++++++++++++----- src/BlockEntities/DispenserEntity.h | 15 ++-- 2 files changed, 95 insertions(+), 27 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 2a32f69d9..7257513df 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -6,8 +6,10 @@ #include "../Simulator/FluidSimulator.h" #include "../Chunk.h" - - +#include "../World.h" +#include "../Entities/ArrowEntity.h" +#include "../Entities/FireChargeEntity.h" +#include "../Matrix4.h" cDispenserEntity::cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : @@ -69,7 +71,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 +85,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 +99,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 +110,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 +130,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 +140,63 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) } break; } - + case E_ITEM_FIRE_CHARGE: { - // TODO: Spawn fireball entity + Vector3d Speed = GetProjectileLookVector(a_Chunk); + + double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); + double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); + + + cFireChargeEntity* fireCharge = new cFireChargeEntity(NULL /*was this*/, MobX, (double) DispY + 0.3, MobZ, Speed); + + + if (fireCharge == NULL) + { + break; + } + if (!fireCharge->Initialize(m_World)) + { + + delete fireCharge; + break; + } + m_World->BroadcastSpawnEntity(*fireCharge); + + m_Contents.ChangeSlotCount(a_SlotNum, -1); + break; } - + + case E_ITEM_ARROW: + { + Vector3d Speed = GetProjectileLookVector(a_Chunk); + + double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); + double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); + + + cArrowEntity* Arrow = new cArrowEntity(NULL /*was this*/, MobX, (double) DispY + 0.3, MobZ, Speed); + + + if (Arrow == NULL) + { + break; + } + if (!Arrow->Initialize(m_World)) + { + + delete Arrow; + break; + } + m_World->BroadcastSpawnEntity(*Arrow); + + m_Contents.ChangeSlotCount(a_SlotNum, -1); + + break; + } + default: { DropFromSlot(a_Chunk, a_SlotNum); @@ -154,8 +206,29 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) } +Vector3d cDispenserEntity::GetProjectileLookVector(cChunk & a_Chunk) +{ + NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); + int Direction = 0; + switch (Meta) + { + case E_META_DROPSPENSER_FACING_YP: Direction = 0; break; // YP & YM don't have associated smoke dirs, just do 4 (centre of block) + case E_META_DROPSPENSER_FACING_YM: Direction = 0; break; + case E_META_DROPSPENSER_FACING_XM: Direction = 90; break; // WEST + case E_META_DROPSPENSER_FACING_XP: Direction = 270; break; // EAST + case E_META_DROPSPENSER_FACING_ZM: Direction = 180; break; + case E_META_DROPSPENSER_FACING_ZP: Direction = 0; break; + } + Matrix4d m; + m.Init(Vector3d(), 0, Direction, 0); + Vector3d Look = m.Transform(Vector3d(0, 0, 1)); + Vector3d Speed = Look * 20; + Speed.y = Speed.y + 1; + + return Speed; +} bool cDispenserEntity::ScoopUpLiquid(int a_SlotNum, short a_BucketItemType) @@ -167,14 +240,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 +268,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,20 +276,16 @@ 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); return true; } - - - - diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index fdfe4e5b4..02a34be37 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -12,11 +12,11 @@ class cDispenserEntity : public cDropSpenserEntity { typedef cDropSpenserEntity super; - + public: // tolua_end - + /// Constructor used for normal operation cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); @@ -25,14 +25,13 @@ public: 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 bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType); - + + // Returns how to aim the projectile + Vector3d GetProjectileLookVector(cChunk & a_Chunk); + /// If the a_BlockInFront is liquidable and the empty bucket can fit, does the m_Contents processing and returns true bool EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum); } ; // tolua_export - - - - From 24137e282bc97497bcf8c50745d2d45da59b1a27 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 26 May 2014 10:05:51 +0200 Subject: [PATCH 129/312] Fixed prefab test initialization. --- src/Generating/Prefab.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index e41907325..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); From 16e4af0793c55533dd999a5c2e8ade4ddd212d72 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Mon, 26 May 2014 10:50:17 +0100 Subject: [PATCH 130/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22befc822..5847cdd17 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/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) [![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) [![Support via Gittip](http://img.shields.io/gittip/mcs_team.svg)](https://www.gittip.com/on/github/mc-server/) [![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. From 69c39648750e2f752212103cc12998f7f73751fc Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Mon, 26 May 2014 10:50:42 +0100 Subject: [PATCH 131/312] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5847cdd17..9b9694841 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/on/github/mc-server/) [![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) [![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 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. From 1d6dbb6278d9700ffaa69717508eac72fde05f59 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Mon, 26 May 2014 12:29:45 +0100 Subject: [PATCH 132/312] Minor fixes. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9b9694841..e6d9492f0 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Normally, you will want to download a pre-compiled version of MCServer from one * [Linux and Raspberry Pi](http://ci.bearbin.net) (Bearbin's CI Server) * [Windows](http://mc-server.xoft.cz) (xoft's nightly build service) -You simply need to download and extract these files before you can use the server. +You simply need to download and extract these files before you can use the server. If you're a more advanced user, you may want to compile the server yourself for more performance. See the [COMPILING.md](https://github.com/mc-server/MCServer/blob/master/COMPILING.md) file for more details. @@ -24,7 +24,7 @@ Contributing MCServer is licensed under the Apache license V2, and we welcome anybody to fork and submit a Pull Request back with their changes, and if you want to join as a permanent member we can add you to the team. -Check out the [CONTRIBUTING.md](https://github.com/mc-server/MCServer/blob/master/CONTRIBUTING.md) file for more infos. +Check out the [CONTRIBUTING.md](https://github.com/mc-server/MCServer/blob/master/CONTRIBUTING.md) file for more details. Other Stuff ----------- @@ -33,7 +33,7 @@ For other stuff, including plugins and discussion, check the [forums](http://for Earn bitcoins for commits or donate to reward the MCServer developers: [![tip for next commit](http://tip4commit.com/projects/74.svg)](http://tip4commit.com/projects/74) -Support Via Gittip: [![Support via Gittip](http://img.shields.io/gittip/on%2Fgithub%2Fmc-server.svg)](https://www.gittip.com/on/github/mc-server/) +Support Us on Gittip: [![Support via Gittip](http://img.shields.io/gittip/mcs_team.svg)](https://www.gittip.com/mcs_team) Travis CI: [![Build Status](http://img.shields.io/travis/mc-server/MCServer.svg)](https://travis-ci.org/mc-server/MCServer) From 74801f564775ae4c6b70834f76167a54b8a84826 Mon Sep 17 00:00:00 2001 From: JoannisO Date: Mon, 26 May 2014 14:47:04 +0200 Subject: [PATCH 133/312] - Added support for more types of projectiles in the Dispenser - Improved the method of spawning projectiles in the world - Added another method for spawning the projectiles --- src/BlockEntities/DispenserEntity.cpp | 82 ++++++++++++++------------- src/BlockEntities/DispenserEntity.h | 7 +++ 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 7257513df..e2032a041 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -9,9 +9,12 @@ #include "../World.h" #include "../Entities/ArrowEntity.h" #include "../Entities/FireChargeEntity.h" +#include "../Entities/ProjectileEntity.h" #include "../Matrix4.h" + + cDispenserEntity::cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) : super(E_BLOCK_DISPENSER, a_BlockX, a_BlockY, a_BlockZ, a_World) { @@ -143,56 +146,37 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_FIRE_CHARGE: { - Vector3d Speed = GetProjectileLookVector(a_Chunk); - - double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); - double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - - - cFireChargeEntity* fireCharge = new cFireChargeEntity(NULL /*was this*/, MobX, (double) DispY + 0.3, MobZ, Speed); - - - if (fireCharge == NULL) - { - break; - } - if (!fireCharge->Initialize(m_World)) - { - - delete fireCharge; - break; - } - m_World->BroadcastSpawnEntity(*fireCharge); - - m_Contents.ChangeSlotCount(a_SlotNum, -1); + spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFireCharge); break; } case E_ITEM_ARROW: { - Vector3d Speed = GetProjectileLookVector(a_Chunk); + spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkArrow); - double MobX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); - double MobZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); + break; + } + case E_ITEM_SNOWBALL: + { + // Not working as there is no such entity yet? + spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkSnowball); - cArrowEntity* Arrow = new cArrowEntity(NULL /*was this*/, MobX, (double) DispY + 0.3, MobZ, Speed); + break; + } + case E_ITEM_EGG: + { + // Not working as there is no such entity yet? + spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkEgg); - if (Arrow == NULL) - { - break; - } - if (!Arrow->Initialize(m_World)) - { + break; + } - delete Arrow; - break; - } - m_World->BroadcastSpawnEntity(*Arrow); - - m_Contents.ChangeSlotCount(a_SlotNum, -1); + case E_ITEM_FIREWORK_ROCKET: + { + spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFirework); break; } @@ -206,6 +190,20 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) } + +void cDispenserEntity::spawnProjectileFromDispenser(cChunk& a_Chunk, int& DispX, int& DispY, int& DispZ, cProjectileEntity::eKind kind) +{ + Vector3d Speed = GetProjectileLookVector(a_Chunk); + cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(DispX, DispZ); + + double EntityX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); + double EntityZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); + + m_World->CreateProjectile((double) EntityX, (double) DispY, (double) EntityZ, cProjectileEntity::pkArrow, NULL, NULL, &Speed); +} + + + Vector3d cDispenserEntity::GetProjectileLookVector(cChunk & a_Chunk) { NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); @@ -231,6 +229,10 @@ Vector3d cDispenserEntity::GetProjectileLookVector(cChunk & a_Chunk) } + + + + bool cDispenserEntity::ScoopUpLiquid(int a_SlotNum, short a_BucketItemType) { cItem LiquidBucket(a_BucketItemType, 1); @@ -289,3 +291,7 @@ bool cDispenserEntity::EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum m_Contents.AddItem(EmptyBucket); return true; } + + + + diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index 02a34be37..9290bee5c 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -29,9 +29,16 @@ private: /// If such a bucket can fit, adds it to m_Contents and returns true bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType); + // Spawns a projectile of the given kind in front of the dispenser + void spawnProjectileFromDispenser(cChunk& a_Chunk, int& DispX, int& DispY, int& DispZ, cProjectileEntity::eKind kind); + // Returns how to aim the projectile Vector3d GetProjectileLookVector(cChunk & a_Chunk); /// If the a_BlockInFront is liquidable and the empty bucket can fit, does the m_Contents processing and returns true bool EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum); } ; // tolua_export + + + + From 6449b5d11b5a07183812189d5eead0734f9dc191 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 26 May 2014 16:38:14 +0200 Subject: [PATCH 134/312] Revert "Add more move checks" This reverts commit 989312c4e7f517ae324e857cb255211e3fd8bb06. --- src/ClientHandle.cpp | 74 ++++++++++---------------------------------- src/ClientHandle.h | 2 +- 2 files changed, 17 insertions(+), 59 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index e7537d74d..83b21ae3c 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -582,37 +582,16 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, return; } - if (m_Player->GetHealth() <= 0) + /* + // TODO: Invalid stance check + if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65)) { - // The player is dead. He can't move :D + LOGD("Invalid stance"); + SendPlayerMoveLook(); return; } - - if (std::isnan(a_PosX) || std::isnan(a_PosY) || std::isnan(a_PosZ) || std::isnan(a_Stance)) - { - LOGWARN("%s was caught trying to crash the server with an invalid position.", m_Player->GetName().c_str()); - Kick("Nope!"); - return; - } - - // Invalid stance check - if (!m_Player->IsInBed()) - { - double Difference = a_Stance - a_PosY; - if ((Difference > 1.65) || (Difference < 1.0)) - { - Kick("Illegal stance!"); - LOGWARN("%s had an illegal stance: %f", m_Player->GetName().c_str(), a_Stance); - return; - } - } - - if ((std::abs(a_PosX) > 32000000.0) || (std::abs(a_PosZ) > 32000000.0)) - { - Kick("Illegal position!"); - return; - } - + */ + // If the player has moved too far, "repair" them: Vector3d Pos(a_PosX, a_PosY, a_PosZ); if ((m_Player->GetPosition() - Pos).SqrLength() > 100 * 100) @@ -1410,7 +1389,7 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO -void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Yaw, float a_Pitch, bool a_IsOnGround) +void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround) { if ((m_Player == NULL) || (m_State != csPlaying)) { @@ -1418,42 +1397,21 @@ void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_ return; } - if (m_Player->GetHealth() <= 0) + /* + // TODO: Invalid stance check + if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65)) { - // The player is dead. He can't move :D - return; - } - - if (std::isnan(a_PosX) || std::isnan(a_PosY) || std::isnan(a_PosZ) || std::isnan(a_Stance)) - { - LOGWARN("%s was caught trying to crash the server with an invalid position.", m_Player->GetName().c_str()); - Kick("Nope!"); - return; - } - - // Invalid stance check - if (!m_Player->IsInBed()) - { - double Difference = a_Stance - a_PosY; - if ((Difference > 1.65) || (Difference < 1.0)) - { - Kick("Illegal stance!"); - LOGWARN("%s had an illegal stance: %f", m_Player->GetName().c_str(), a_Stance); - return; - } - } - - if ((std::abs(a_PosX) > 32000000.0) || (std::abs(a_PosZ) > 32000000.0)) - { - Kick("Illegal position!"); + LOGD("Invalid stance"); + SendPlayerMoveLook(); return; } + */ m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ)); m_Player->SetStance (a_Stance); m_Player->SetTouchGround(a_IsOnGround); - m_Player->SetHeadYaw (a_Yaw); - m_Player->SetYaw (a_Yaw); + m_Player->SetHeadYaw (a_Rotation); + m_Player->SetYaw (a_Rotation); m_Player->SetPitch (a_Pitch); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 04d93e2c0..659c67658 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -225,7 +225,7 @@ public: void HandlePing (void); void HandlePlayerAbilities (bool a_CanFly, bool a_IsFlying, float FlyingSpeed, float WalkingSpeed); void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround); - void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Yaw, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay) + void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay) void HandlePlayerPos (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround); void HandlePluginMessage (const AString & a_Channel, const AString & a_Message); void HandleRespawn (void); From 2194238ef0b376353e7260df5a964976d0b72c5f Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Mon, 26 May 2014 17:17:54 +0100 Subject: [PATCH 135/312] Update main.css --- MCServer/Plugins/APIDump/main.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/main.css b/MCServer/Plugins/APIDump/main.css index aa26bd186..0a779bfb8 100644 --- a/MCServer/Plugins/APIDump/main.css +++ b/MCServer/Plugins/APIDump/main.css @@ -39,7 +39,8 @@ pre body { - min-width: 800px; + min-width: 400px; + max-width: 900px; width: 95%; margin: 10px auto; background-color: white; From 0a3570bc9daab9fb8772dee48aab1ba6bf4da92a Mon Sep 17 00:00:00 2001 From: archshift Date: Mon, 26 May 2014 14:13:40 -0700 Subject: [PATCH 136/312] ClientHandle.cpp: remove redundant code HandlePlayerMoveLook() calls HandlePlayerPos() and HandlePlayerLook() to reduce code redundancy. --- src/ClientHandle.cpp | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 83b21ae3c..4aa42a489 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1391,28 +1391,8 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround) { - if ((m_Player == NULL) || (m_State != csPlaying)) - { - // The client hasn't been spawned yet and sends nonsense, we know better - return; - } - - /* - // TODO: Invalid stance check - if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65)) - { - LOGD("Invalid stance"); - SendPlayerMoveLook(); - return; - } - */ - - m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ)); - m_Player->SetStance (a_Stance); - m_Player->SetTouchGround(a_IsOnGround); - m_Player->SetHeadYaw (a_Rotation); - m_Player->SetYaw (a_Rotation); - m_Player->SetPitch (a_Pitch); + HandlePlayerPos(a_PosX, a_PosY, a_PosZ, a_Stance, a_IsOnGround); + HandlePlayerLook(a_Rotation, a_Pitch, a_IsOnGround); } From c204735f3840d2199c48b13bd26e9b8d80394b83 Mon Sep 17 00:00:00 2001 From: archshift Date: Tue, 27 May 2014 00:28:46 -0700 Subject: [PATCH 137/312] ClientHandle.cpp: Process look before pos --- src/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 4aa42a489..9b03bead9 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1391,8 +1391,8 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround) { - HandlePlayerPos(a_PosX, a_PosY, a_PosZ, a_Stance, a_IsOnGround); HandlePlayerLook(a_Rotation, a_Pitch, a_IsOnGround); + HandlePlayerPos(a_PosX, a_PosY, a_PosZ, a_Stance, a_IsOnGround); } From 1128dc783f4ee0913f3395c0a79ebdbbce2cfdee Mon Sep 17 00:00:00 2001 From: Joannis Date: Tue, 27 May 2014 11:08:06 +0200 Subject: [PATCH 138/312] - Fixed the ampersands and asterisks to fit the format. - Fixed the method "SpawnProjectileFromDispenser" to use CamelCasing. --- src/BlockEntities/DispenserEntity.cpp | 14 +++++++------- src/BlockEntities/DispenserEntity.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index e2032a041..0f64118ef 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -146,14 +146,14 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_FIRE_CHARGE: { - spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFireCharge); + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFireCharge); break; } case E_ITEM_ARROW: { - spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkArrow); + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkArrow); break; } @@ -161,7 +161,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_SNOWBALL: { // Not working as there is no such entity yet? - spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkSnowball); + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkSnowball); break; } @@ -169,14 +169,14 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_EGG: { // Not working as there is no such entity yet? - spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkEgg); + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkEgg); break; } case E_ITEM_FIREWORK_ROCKET: { - spawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFirework); + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFirework); break; } @@ -191,7 +191,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) -void cDispenserEntity::spawnProjectileFromDispenser(cChunk& a_Chunk, int& DispX, int& DispY, int& DispZ, cProjectileEntity::eKind kind) +void cDispenserEntity::SpawnProjectileFromDispenser(cChunk & a_Chunk, int & DispX, int & DispY, int & DispZ, cProjectileEntity::eKind kind) { Vector3d Speed = GetProjectileLookVector(a_Chunk); cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(DispX, DispZ); @@ -199,7 +199,7 @@ void cDispenserEntity::spawnProjectileFromDispenser(cChunk& a_Chunk, int& DispX, double EntityX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); double EntityZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - m_World->CreateProjectile((double) EntityX, (double) DispY, (double) EntityZ, cProjectileEntity::pkArrow, NULL, NULL, &Speed); + m_World->CreateProjectile((double) EntityX, (double) DispY, (double) EntityZ, cProjectileEntity::pkArrow, NULL, NULL, & Speed); } diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index 9290bee5c..8bc2475c9 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -30,7 +30,7 @@ private: bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType); // Spawns a projectile of the given kind in front of the dispenser - void spawnProjectileFromDispenser(cChunk& a_Chunk, int& DispX, int& DispY, int& DispZ, cProjectileEntity::eKind kind); + void SpawnProjectileFromDispenser(cChunk& a_Chunk, int& DispX, int& DispY, int& DispZ, cProjectileEntity::eKind kind); // Returns how to aim the projectile Vector3d GetProjectileLookVector(cChunk & a_Chunk); From 19df18c46199f06f3bf2058cc0efee9126e7670a Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 27 May 2014 12:44:56 +0100 Subject: [PATCH 139/312] Fixed test globals to work with precompiled headers --- src/ChunkData.cpp | 4 - src/Globals.h | 48 ++++++++--- tests/ChunkData/ArraytoCoord.cpp | 2 +- tests/ChunkData/Coordinates.cpp | 2 +- tests/ChunkData/Copies.cpp | 2 +- tests/ChunkData/creatable.cpp | 2 +- tests/TestGlobals.h | 139 ------------------------------- 7 files changed, 40 insertions(+), 159 deletions(-) delete mode 100644 tests/TestGlobals.h diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 79029f0cf..c41dcb265 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -1,9 +1,5 @@ -#ifdef TEST_GLOBALS -#include "TestGlobals.h" -#else #include "Globals.h" -#endif #include "ChunkData.h" cChunkData::cChunkData() diff --git a/src/Globals.h b/src/Globals.h index 71e9191e4..85cfd2f18 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -225,16 +225,28 @@ template class SizeChecker; +#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,22 @@ template class SizeChecker; #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 + { + }; + + #define ASSERT(x) do { if (!(x)) { throw cAssertFailure();} } while (0) + #define testassert(x) do { if(!(x)) { exit(1); } } while (0) + #define CheckAsserts(x) do { try {x} catch (cAssertFailure) { break; } 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/tests/ChunkData/ArraytoCoord.cpp b/tests/ChunkData/ArraytoCoord.cpp index 1138fb5b6..37533de77 100644 --- a/tests/ChunkData/ArraytoCoord.cpp +++ b/tests/ChunkData/ArraytoCoord.cpp @@ -1,5 +1,5 @@ -#include "TestGlobals.h" +#include "Globals.h" #include "ChunkData.h" diff --git a/tests/ChunkData/Coordinates.cpp b/tests/ChunkData/Coordinates.cpp index f02b68d40..938c66dcc 100644 --- a/tests/ChunkData/Coordinates.cpp +++ b/tests/ChunkData/Coordinates.cpp @@ -1,5 +1,5 @@ -#include "TestGlobals.h" +#include "Globals.h" #include "ChunkData.h" diff --git a/tests/ChunkData/Copies.cpp b/tests/ChunkData/Copies.cpp index b10ddb759..78a458f5b 100644 --- a/tests/ChunkData/Copies.cpp +++ b/tests/ChunkData/Copies.cpp @@ -1,5 +1,5 @@ -#include "TestGlobals.h" +#include "Globals.h" #include "ChunkData.h" diff --git a/tests/ChunkData/creatable.cpp b/tests/ChunkData/creatable.cpp index 74025cb14..1321bf49b 100644 --- a/tests/ChunkData/creatable.cpp +++ b/tests/ChunkData/creatable.cpp @@ -1,5 +1,5 @@ -#include "TestGlobals.h" +#include "Globals.h" #include "ChunkData.h" int main(int argc, char** argv) diff --git a/tests/TestGlobals.h b/tests/TestGlobals.h deleted file mode 100644 index ea43de733..000000000 --- a/tests/TestGlobals.h +++ /dev/null @@ -1,139 +0,0 @@ - - -#include -#include -#include - - -// Compiler-dependent stuff: -#if defined(_MSC_VER) - // MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether - #pragma warning(disable:4481) - - // Disable some warnings that we don't care about: - #pragma warning(disable:4100) // Unreferenced formal parameter - - // Useful warnings from warning level 4: - #pragma warning(3 : 4127) // Conditional expression is constant - #pragma warning(3 : 4189) // Local variable is initialized but not referenced - #pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed/unsigned mismatch - #pragma warning(3 : 4310) // Cast truncates constant value - #pragma warning(3 : 4389) // Signed/unsigned mismatch - #pragma warning(3 : 4505) // Unreferenced local function has been removed - #pragma warning(3 : 4701) // Potentially unitialized local variable used - #pragma warning(3 : 4702) // Unreachable code - #pragma warning(3 : 4706) // Assignment within conditional expression - - // Disabling this warning, because we know what we're doing when we're doing this: - #pragma warning(disable: 4355) // 'this' used in initializer list - - // Disabled because it's useless: - #pragma warning(disable: 4512) // 'class': assignment operator could not be generated - reported for each class that has a reference-type member - - // 2014_01_06 xoft: Disabled this warning because MSVC is stupid and reports it in obviously wrong places - // #pragma warning(3 : 4244) // Conversion from 'type1' to 'type2', possible loss of data - - #define OBSOLETE __declspec(deprecated) - - // No alignment needed in MSVC - #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)? - #define abstract - - // override is part of c++11 - #if __cplusplus < 201103L - #define override - #endif - - #define OBSOLETE __attribute__((deprecated)) - - #define ALIGN_8 __attribute__((aligned(8))) - #define ALIGN_16 __attribute__((aligned(16))) - - // 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" - - /* - // Copy and uncomment this into another #elif section based on your compiler identification - - // Explicitly mark classes as abstract (no instances can be created) - #define abstract - - // Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class) - #define override - - // Mark functions as obsolete, so that their usage results in a compile-time warning - #define OBSOLETE - - // Mark types / variables for alignment. Do the platforms need it? - #define ALIGN_8 - #define ALIGN_16 - */ - -#endif - - - -// Integral types with predefined sizes: -typedef long long Int64; -typedef int Int32; -typedef short Int16; - -typedef unsigned long long UInt64; -typedef unsigned int UInt32; -typedef unsigned short UInt16; - -typedef unsigned char Byte; - -class cAssertFailure -{ -}; - -#define ASSERT(x) do { if (!(x)) { throw cAssertFailure();} } while (0) -#define testassert(x) do { if(!(x)) { exit(1); } } while (0) -#define CheckAsserts(x) do { try {x} catch (cAssertFailure) { break; } exit(1); } while (0) - -#ifndef TOLUA_TEMPLATE_BIND -#define TOLUA_TEMPLATE_BIND(x) -#endif - -// A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc -#define UNUSED(X) (void)(X) - -// Logging functions -void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1,2); - -void inline LOGERROR(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - vprintf(a_Format, argList); - va_end(argList); -} - - From 6c25c356c7769b64fd43b0dd2611deb18bdd5619 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 27 May 2014 21:18:15 +0200 Subject: [PATCH 140/312] Biome generators: biome lists can contain spaces. --- src/Generating/BioGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) From e06f786f1151e1934890a2555de080b1a6860ec4 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Tue, 27 May 2014 20:24:04 +0100 Subject: [PATCH 141/312] Stuff. --- MCServer/Plugins/APIDump/main.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/main.css b/MCServer/Plugins/APIDump/main.css index 0a779bfb8..8041e0d01 100644 --- a/MCServer/Plugins/APIDump/main.css +++ b/MCServer/Plugins/APIDump/main.css @@ -40,7 +40,7 @@ pre body { min-width: 400px; - max-width: 900px; + max-width: 1200px; width: 95%; margin: 10px auto; background-color: white; From ff99373237178e9f7da02f51581f9a83d0e624d9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 27 May 2014 22:05:50 +0200 Subject: [PATCH 142/312] cPieceGenerator chooses starting pieces based on weights. Fixes #1033. --- src/Generating/PieceGenerator.cpp | 26 +++++++++++++++++++++++++- src/Generating/PieceGenerator.h | 9 +++++++++ src/Generating/PrefabPiecePool.cpp | 9 +++++++++ src/Generating/PrefabPiecePool.h | 1 + 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index 1880a20d5..5de231f75 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -362,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 21c155c96..fd8576706 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -120,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; diff --git a/src/Generating/PrefabPiecePool.cpp b/src/Generating/PrefabPiecePool.cpp index ed9340815..ad97ab0e7 100644 --- a/src/Generating/PrefabPiecePool.cpp +++ b/src/Generating/PrefabPiecePool.cpp @@ -101,6 +101,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..695ab4ea5 100644 --- a/src/Generating/PrefabPiecePool.h +++ b/src/Generating/PrefabPiecePool.h @@ -70,6 +70,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; } ; From 71256c98ed748d5cd789f94404e7984e11bdf115 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 27 May 2014 22:06:49 +0200 Subject: [PATCH 143/312] Fixed testing weights in PlainsVillages. --- src/Generating/Prefabs/PlainsVillagePrefabs.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp index fee6610c9..f8cf867e5 100644 --- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -4601,7 +4601,7 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] = true, // DefaultWeight: - 0, + 100, // DepthWeight: "", @@ -5048,7 +5048,7 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] = false, // DefaultWeight: - 1000, + 100, // DepthWeight: "", @@ -5259,7 +5259,7 @@ const cPrefab::sDef g_PlainsVillageStartingPrefabs[] = true, // DefaultWeight: - 0, + 100, // DepthWeight: "", From 6b41d1a4220aa032f53b67637bbc3276272e5047 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 27 May 2014 22:08:20 +0200 Subject: [PATCH 144/312] Added AlchemistVillage prefabs (Thanks, KingsCraftAu). --- .../Prefabs/AlchemistVillagePrefabs.cpp | 2969 +++++++++++++++++ .../Prefabs/AlchemistVillagePrefabs.h | 15 + src/Generating/VillageGen.cpp | 32 +- 3 files changed, 3007 insertions(+), 9 deletions(-) create mode 100644 src/Generating/Prefabs/AlchemistVillagePrefabs.cpp create mode 100644 src/Generating/Prefabs/AlchemistVillagePrefabs.h diff --git a/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp new file mode 100644 index 000000000..32ffe5b88 --- /dev/null +++ b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp @@ -0,0 +1,2969 @@ + +// 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, 9, // SizeX = 11, SizeY = 12, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 11, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "A:101: 0\n" /* ironbars */ + "B: 64:12\n" /* wooddoorblock */ + "C:128: 2\n" /* sandstonestairs */ + "D: 24: 1\n" /* sandstone */ + "E: 44: 9\n" /* step */ + "F:126: 8\n" /* woodenslab */ + "G:128: 7\n" /* sandstonestairs */ + "H: 44: 1\n" /* step */ + "I: 64: 7\n" /* wooddoorblock */ + "J: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: 50: 3\n" /* torch */ + "z:171: 8\n" /* carpet */, + + // 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" + + // 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" + + // 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" + + // 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" + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "ccccccccccc" + /* 1 */ "ccccccccccc" + /* 2 */ "ccnnnnnnncc" + /* 3 */ "cnnnnnnnnnc" + /* 4 */ "cnnnnnnnnnc" + /* 5 */ "cnnnnnnnnnc" + /* 6 */ "cnnnnnnnnnc" + /* 7 */ "cnonnnnnnnc" + /* 8 */ "cnccccccccc" + + // 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" + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "...p...p..." + /* 1 */ "..........." + /* 2 */ "pbbb...bbbp" + /* 3 */ "b..y...y..b" + /* 4 */ "b.z.....z.b" + /* 5 */ "A.........A" + /* 6 */ "b.........b" + /* 7 */ "b.......z.b" + /* 8 */ "pBbbAAAbbbp" + + // Level 7 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "...C...C..." + /* 1 */ "...D...b..." + /* 2 */ "pbbbqEsbbbp" + /* 3 */ "bFFFFFFFFFb" + /* 4 */ "bFFFFFFFFFb" + /* 5 */ "sFFFFFFFFFq" + /* 6 */ "bFFFFFFFFFb" + /* 7 */ "bFFFFFFFFFb" + /* 8 */ "pbbbGGGbbbp" + + // Level 8 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "bHHHHbHHHHb" + /* 3 */ "HpbbbbbbbpH" + /* 4 */ "Hb.......bH" + /* 5 */ "bb.......bb" + /* 6 */ "Hb.......bH" + /* 7 */ "HpIbbbbbbpH" + /* 8 */ "bH.HHbHHHHb" + + // Level 9 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ ".pbbAAAbbp." + /* 4 */ ".b.......b." + /* 5 */ ".A.......A." + /* 6 */ ".b.......b." + /* 7 */ ".pBbAAAbbp." + /* 8 */ "..........." + + // Level 10 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ ".pbbJJJbbp." + /* 4 */ ".bFFFFFFFb." + /* 5 */ ".sFFFFFFFq." + /* 6 */ ".bFFFFFFFb." + /* 7 */ ".pbbGGGbbp." + /* 8 */ "..........." + + // Level 11 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ ".bHHHbHHHb." + /* 4 */ ".H.......H." + /* 5 */ ".b.......b." + /* 6 */ ".H.......H." + /* 7 */ ".bHHHbHHHb." + /* 8 */ "...........", + + // 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: + 100, + + // 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, 9, // SizeX = 11, SizeY = 8, SizeZ = 9 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 7, 8, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "A: 44: 1\n" /* step */ + "B: 64: 3\n" /* wooddoorblock */ + "C: 64: 8\n" /* wooddoorblock */ + "D: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: 50: 3\n" /* torch */ + "s:171: 8\n" /* carpet */ + "t:101: 0\n" /* ironbars */ + "u: 64:12\n" /* wooddoorblock */ + "v:128: 2\n" /* sandstonestairs */ + "w: 24: 1\n" /* sandstone */ + "x: 44: 9\n" /* step */ + "y:126: 8\n" /* woodenslab */ + "z:128: 7\n" /* sandstonestairs */, + + // 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" + + // 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" + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "...c...c..." + /* 1 */ "..........." + /* 2 */ "cddd...dddc" + /* 3 */ "d..r...r..d" + /* 4 */ "d.s.....s.d" + /* 5 */ "t.........t" + /* 6 */ "d.........d" + /* 7 */ "d.......s.d" + /* 8 */ "cuddtttdddc" + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "...v...v..." + /* 1 */ "...w...d..." + /* 2 */ "cdddexgdddc" + /* 3 */ "dyyyyyyyyyd" + /* 4 */ "dyyyyyyyyyd" + /* 5 */ "gyyyyyyyyye" + /* 6 */ "dyyyyyyyyyd" + /* 7 */ "dyyyyyyyyyd" + /* 8 */ "cdddzzzdddc" + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "dAAAAdAAAAd" + /* 3 */ "AcdddddddcA" + /* 4 */ "Ad.......dA" + /* 5 */ "dd.......dd" + /* 6 */ "Ad.......dA" + /* 7 */ "AcBddddddcA" + /* 8 */ "dA.AAdAAAAd" + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ ".cddtttddc." + /* 4 */ ".d.......d." + /* 5 */ ".t.......t." + /* 6 */ ".d.......d." + /* 7 */ ".cCdtttddc." + /* 8 */ "..........." + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ ".cddDDDddc." + /* 4 */ ".dyyyyyyyd." + /* 5 */ ".gyyyyyyye." + /* 6 */ ".dyyyyyyyd." + /* 7 */ ".cddzzzddc." + /* 8 */ "..........." + + // Level 7 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "..........." + /* 1 */ "..........." + /* 2 */ "..........." + /* 3 */ ".dAAAdAAAd." + /* 4 */ ".A.......A." + /* 5 */ ".d.......d." + /* 6 */ ".A.......A." + /* 7 */ ".dAAAdAAAd." + /* 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, + }, // BarWithoutBasement + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // BlackSmith: + // The data has been exported from the gallery Desert, area index 92, ID 633, created by STR_Warrior + { + // Size: + 11, 5, 13, // SizeX = 11, SizeY = 5, SizeZ = 13 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 4, 12, // 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 */, + + // Block data: + // Level 0 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "aaaaaaaaaaa" + /* 1 */ "aaaaaaaaaaa" + /* 2 */ "aaaaaaaabaa" + /* 3 */ "acaaacabbba" + /* 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 */ "......c...c" + /* 5 */ "...f..c...c" + /* 6 */ ".....dc...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 */ "......c...n" + /* 7 */ "......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 */ ".rsssscsssu" + /* 7 */ ".rsssscsssu" + /* 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 */ "......w...w" + /* 7 */ ".w....w...c" + /* 8 */ "cwwwwwc...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: + 100, + + // 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): + 0, 0, 0, // MinX, MinY, MinZ + 14, 12, 10, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "A:128: 2\n" /* sandstonestairs */ + "B:128: 0\n" /* sandstonestairs */ + "C: 87: 0\n" /* netherstone */ + "D:128: 3\n" /* sandstonestairs */ + "E: 51: 0\n" /* fire */ + "F: 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: 2\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:140: 0\n" /* flowerpotblock */ + "p: 64: 8\n" /* wooddoorblock */ + "q: 69:12\n" /* lever */ + "r: 44:10\n" /* step */ + "s:128: 1\n" /* sandstonestairs */ + "t: 47: 0\n" /* bookshelf */ + "u: 96:12\n" /* trapdoor */ + "v:128: 4\n" /* sandstonestairs */ + "w:128: 5\n" /* sandstonestairs */ + "x:128: 7\n" /* sandstonestairs */ + "y: 44: 1\n" /* step */ + "z:128: 6\n" /* sandstonestairs */, + + // 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 */ "....d......od.c" + /* 2 */ "....p.......d.." + /* 3 */ "....d.......p.." + /* 4 */ "....d.q...l.d.." + /* 5 */ "....dddd.dddd.c" + /* 6 */ "....n.......n.." + /* 7 */ "mmmmn.......n.." + /* 8 */ "mmmmn.......n.." + /* 9 */ "mmmmd.......d.." + /* 10 */ "mmmmcddnnnddc.." + + // Level 3 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "....cdddddddc.." + /* 1 */ "....drrrrrrrdds" + /* 2 */ "....drrrrrrrd.." + /* 3 */ "....drrrrrrrd.." + /* 4 */ "....dtttrrurd.." + /* 5 */ "....dddddddddds" + /* 6 */ "....vrrrrrrrw.." + /* 7 */ "mmmmvrrrrrrrw.." + /* 8 */ "mmmmvrrrrrrrw.." + /* 9 */ "mmmmdrrrrrrrd.." + /* 10 */ "mmmmcddxxxddc.." + + // Level 4 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "....dyyydyyyd.." + /* 1 */ "....ycdddddcy.." + /* 2 */ "....yd.....dy.." + /* 3 */ "....yd.....dy.." + /* 4 */ "....yd.....dy.." + /* 5 */ "....dcdd.ddcd.." + /* 6 */ "....y.......y.." + /* 7 */ "mmmmy.......y.." + /* 8 */ "mmmmy.......y.." + /* 9 */ "mmmmy.......y.." + /* 10 */ "mmmmdyyydyyyd.." + + // 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 */ ".....cddzddc..." + /* 2 */ ".....vrrrrrw..." + /* 3 */ ".....vrrrrrw..." + /* 4 */ ".....vrrrrrw..." + /* 5 */ ".....cdddddc..." + /* 6 */ "..............." + /* 7 */ "..............." + /* 8 */ "..............." + /* 9 */ "..............." + /* 10 */ "..............." + + // Level 7 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ ".....dyydyyd..." + /* 2 */ ".....y.ddd.y..." + /* 3 */ ".....d.ddd.d..." + /* 4 */ ".....y.ddd.y..." + /* 5 */ ".....dyydyyd..." + /* 6 */ "..............." + /* 7 */ "..............." + /* 8 */ "..............." + /* 9 */ "..............." + /* 10 */ "..............." + + // Level 8 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "..............." + /* 2 */ ".......cAc....." + /* 3 */ ".......BCs....." + /* 4 */ ".......cDc....." + /* 5 */ "..............." + /* 6 */ "..............." + /* 7 */ "..............." + /* 8 */ "..............." + /* 9 */ "..............." + /* 10 */ "..............." + + // Level 9 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "..............." + /* 2 */ ".......c.c....." + /* 3 */ "........E......" + /* 4 */ ".......c.c....." + /* 5 */ "..............." + /* 6 */ "..............." + /* 7 */ "..............." + /* 8 */ "..............." + /* 9 */ "..............." + /* 10 */ "..............." + + // Level 10 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "..............." + /* 2 */ ".......c.c....." + /* 3 */ "..............." + /* 4 */ ".......c.c....." + /* 5 */ "..............." + /* 6 */ "..............." + /* 7 */ "..............." + /* 8 */ "..............." + /* 9 */ "..............." + /* 10 */ "..............." + + // Level 11 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "..............." + /* 2 */ ".......ddd....." + /* 3 */ ".......dFd....." + /* 4 */ ".......ddd....." + /* 5 */ "..............." + /* 6 */ "..............." + /* 7 */ "..............." + /* 8 */ "..............." + /* 9 */ "..............." + /* 10 */ "..............." + + // Level 12 + /* z\x* 11111 */ + /* * 012345678901234 */ + /* 0 */ "..............." + /* 1 */ "..............." + /* 2 */ ".......y.y....." + /* 3 */ "..............." + /* 4 */ ".......y.y....." + /* 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: + 100, + + // 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): + 0, 0, 0, // MinX, MinY, MinZ + 6, 10, 6, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 4, 4, 6, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 6, 4, 10, // 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 */ "aaaaaaa" + /* 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): + 0, 0, 0, // MinX, MinY, MinZ + 8, 4, 6, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 4, 4, 10, // 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: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: 8\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: 5\n" /* sandstonestairs */ + "u:128: 7\n" /* sandstonestairs */ + "v: 44: 1\n" /* step */ + "w: 96: 7\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 */ "tssst" + /* 6 */ "tssst" + /* 7 */ "tssst" + /* 8 */ "dsssd" + /* 9 */ "dsssd" + /* 10 */ "cdudc" + + // Level 4 + /* z\x* 01234 */ + /* 0 */ "....." + /* 1 */ "....." + /* 2 */ "dvdvd" + /* 3 */ "vw..v" + /* 4 */ "v...v" + /* 5 */ "v...v" + /* 6 */ "d...d" + /* 7 */ "v...v" + /* 8 */ "v...v" + /* 9 */ "v...v" + /* 10 */ "dvdvd", + + // 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): + 0, 0, 0, // MinX, MinY, MinZ + 8, 4, 8, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 8, 4, 8, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 8, 4, 10, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 4, 7, 6, // 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): + 0, 0, 0, // MinX, MinY, MinZ + 14, 7, 8, // 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 */, + + // 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 */ "...cdddc......." + /* 4 */ "...dnnnd......." + /* 5 */ "...dnnnd......." + /* 6 */ "...dnnnd......." + /* 7 */ "...cdddc......." + /* 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: + 100, + + // 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): + 0, 0, 0, // MinX, MinY, MinZ + 10, 8, 8, // 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: + 100, + + // 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): + 0, 0, 0, // MinX, MinY, MinZ + 11, 9, 10, // 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: 6\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: + 100, + + // 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): + 0, 0, 0, // MinX, MinY, MinZ + 8, 4, 10, // 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 */ "mmmmcrdrd" + /* 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 +}; // 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/VillageGen.cpp b/src/Generating/VillageGen.cpp index cb1f4fe0d..dfcdf6ef7 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "VillageGen.h" +#include "Prefabs/AlchemistVillagePrefabs.h" #include "Prefabs/JapaneseVillagePrefabs.h" #include "Prefabs/PlainsVillagePrefabs.h" #include "Prefabs/SandVillagePrefabs.h" @@ -274,6 +275,12 @@ protected: } + 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); @@ -311,18 +318,25 @@ protected: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cVillageGen: -/** The prefabs for the sand village. */ static cVillagePiecePool g_SandVillage(g_SandVillagePrefabs, g_SandVillagePrefabsCount, g_SandVillageStartingPrefabs, g_SandVillageStartingPrefabsCount); - -/** The prefabs for the flat-roofed sand village. */ static cVillagePiecePool g_SandFlatRoofVillage(g_SandFlatRoofVillagePrefabs, g_SandFlatRoofVillagePrefabsCount, g_SandFlatRoofVillageStartingPrefabs, g_SandFlatRoofVillageStartingPrefabsCount); - -/** The prefabs for the plains village. */ +static cVillagePiecePool g_AlchemistVillage(g_AlchemistVillagePrefabs, g_AlchemistVillagePrefabsCount, g_AlchemistVillageStartingPrefabs, g_AlchemistVillageStartingPrefabsCount); static cVillagePiecePool g_PlainsVillage(g_PlainsVillagePrefabs, g_PlainsVillagePrefabsCount, g_PlainsVillageStartingPrefabs, g_PlainsVillageStartingPrefabsCount); - -/** The prefabs for the Japanese village. */ 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, +} ; + @@ -356,8 +370,8 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ cVillagePiecePool * VillagePrefabs = NULL; BLOCKTYPE RoadBlock = E_BLOCK_GRAVEL; int rnd = m_Noise.IntNoise2DInt(a_OriginX, a_OriginZ) / 11; - cVillagePiecePool * PlainsVillage = (rnd % 2 == 0) ? &g_PlainsVillage : &g_JapaneseVillage; - cVillagePiecePool * DesertVillage = (rnd % 2 == 0) ? &g_SandVillage : &g_SandFlatRoofVillage; + 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]) From e5fd782524cdf4b838ad689baef44a61aa4933c2 Mon Sep 17 00:00:00 2001 From: Joannis Date: Wed, 28 May 2014 09:10:09 +0200 Subject: [PATCH 145/312] - Implemented vertical dispensing for projectiles. - Fixed some terrible commit issues on my side. --- src/BlockEntities/DispenserEntity.cpp | 54 +++++++++++++++++++-------- src/BlockEntities/DispenserEntity.h | 2 +- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 0f64118ef..638a844e6 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -147,6 +147,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_FIRE_CHARGE: { SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFireCharge); + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; } @@ -154,6 +155,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_ARROW: { SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkArrow); + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; } @@ -162,6 +164,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { // Not working as there is no such entity yet? SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkSnowball); + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; } @@ -170,6 +173,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { // Not working as there is no such entity yet? SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkEgg); + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; } @@ -177,6 +181,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_FIREWORK_ROCKET: { SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFirework); + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; } @@ -199,7 +204,7 @@ void cDispenserEntity::SpawnProjectileFromDispenser(cChunk & a_Chunk, int & Disp double EntityX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); double EntityZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - m_World->CreateProjectile((double) EntityX, (double) DispY, (double) EntityZ, cProjectileEntity::pkArrow, NULL, NULL, & Speed); + m_World->CreateProjectile((double) EntityX, (double) DispY + 0.5, (double) EntityZ, cProjectileEntity::pkArrow, NULL, NULL, &Speed); } @@ -210,22 +215,45 @@ Vector3d cDispenserEntity::GetProjectileLookVector(cChunk & a_Chunk) int Direction = 0; switch (Meta) { - case E_META_DROPSPENSER_FACING_YP: Direction = 0; break; // YP & YM don't have associated smoke dirs, just do 4 (centre of block) - case E_META_DROPSPENSER_FACING_YM: Direction = 0; break; - case E_META_DROPSPENSER_FACING_XM: Direction = 90; break; // WEST - case E_META_DROPSPENSER_FACING_XP: Direction = 270; break; // EAST + case E_META_DROPSPENSER_FACING_YP: Direction = -1; break; // UP + case E_META_DROPSPENSER_FACING_YM: Direction = -2; break; // DOWN + case E_META_DROPSPENSER_FACING_XM: Direction = 90; break; // WEST + case E_META_DROPSPENSER_FACING_XP: Direction = 270; break; // EAST case E_META_DROPSPENSER_FACING_ZM: Direction = 180; break; case E_META_DROPSPENSER_FACING_ZP: Direction = 0; break; } - Matrix4d m; - m.Init(Vector3d(), 0, Direction, 0); - Vector3d Look = m.Transform(Vector3d(0, 0, 1)); + if(Direction >= 0) + { + Matrix4d m; + m.Init(Vector3d(), 0, Direction, 0); + Vector3d Look = m.Transform(Vector3d(0, 0, 1)); - Vector3d Speed = Look * 20; - Speed.y = Speed.y + 1; + Vector3d Speed = Look * 20; + Speed.y = Speed.y + 1; - return Speed; + return Speed; + + } else if(Direction == -1) + { + Matrix4d m; + m.Init(Vector3d(), 0, 180, 0); + Vector3d Look = m.Transform(Vector3d(0, 1, 0)); + + Vector3d Speed = Look * 20; + + return Speed; + + } else { + + Matrix4d m; + m.Init(Vector3d(), 0, -360, 0); + Vector3d Look = m.Transform(Vector3d(0, -1, 0)); + + Vector3d Speed = Look * 20; + + return Speed; + } } @@ -291,7 +319,3 @@ bool cDispenserEntity::EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum m_Contents.AddItem(EmptyBucket); return true; } - - - - diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index 8bc2475c9..0b7cd6bea 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -30,7 +30,7 @@ private: bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType); // Spawns a projectile of the given kind in front of the dispenser - void SpawnProjectileFromDispenser(cChunk& a_Chunk, int& DispX, int& DispY, int& DispZ, cProjectileEntity::eKind kind); + void SpawnProjectileFromDispenser(cChunk & a_Chunk, int & DispX, int & DispY, int & DispZ, cProjectileEntity::eKind kind); // Returns how to aim the projectile Vector3d GetProjectileLookVector(cChunk & a_Chunk); From 5a9e49fbeb582e47df7359d351fe952dcb0f536b Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 28 May 2014 11:49:36 +0100 Subject: [PATCH 146/312] Fix cmake errors in msvc --- SetFlags.cmake | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SetFlags.cmake b/SetFlags.cmake index d9d0409e2..6e2417a51 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -184,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;Coverage" 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) From 4bc02781af063456db438885d7f3cc8830d5cd92 Mon Sep 17 00:00:00 2001 From: JoannisO Date: Wed, 28 May 2014 14:34:33 +0200 Subject: [PATCH 147/312] - Fixed an issue where dispensers would only shoot arrows (appearantly some commits didn't come through) - Cleaned up the code according to suggestions. --- src/BlockEntities/DispenserEntity.cpp | 57 +++++++++++---------------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 638a844e6..2b0487c4a 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -198,13 +198,13 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) void cDispenserEntity::SpawnProjectileFromDispenser(cChunk & a_Chunk, int & DispX, int & DispY, int & DispZ, cProjectileEntity::eKind kind) { - Vector3d Speed = GetProjectileLookVector(a_Chunk); + Vector3d Angle = GetProjectileLookVector(a_Chunk); cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(DispX, DispZ); double EntityX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); double EntityZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - m_World->CreateProjectile((double) EntityX, (double) DispY + 0.5, (double) EntityZ, cProjectileEntity::pkArrow, NULL, NULL, &Speed); + m_World->CreateProjectile((double) EntityX, (double) DispY + 0.5, (double) EntityZ, kind, NULL, NULL, &Angle); } @@ -213,47 +213,38 @@ Vector3d cDispenserEntity::GetProjectileLookVector(cChunk & a_Chunk) { NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); int Direction = 0; + Matrix4d m; + Vector3d Look; + switch (Meta) { - case E_META_DROPSPENSER_FACING_YP: Direction = -1; break; // UP - case E_META_DROPSPENSER_FACING_YM: Direction = -2; break; // DOWN + case E_META_DROPSPENSER_FACING_YP: + m.Init(Vector3d(), 0, 180, 0); + Look = m.Transform(Vector3d(0, 1, 0)); + + return Look * 20; // UP + break; + + case E_META_DROPSPENSER_FACING_YM: + m.Init(Vector3d(), 0, -360, 0); + Look = m.Transform(Vector3d(0, -1, 0)); + + return Look * 20;; // DOWN + break; + case E_META_DROPSPENSER_FACING_XM: Direction = 90; break; // WEST case E_META_DROPSPENSER_FACING_XP: Direction = 270; break; // EAST case E_META_DROPSPENSER_FACING_ZM: Direction = 180; break; case E_META_DROPSPENSER_FACING_ZP: Direction = 0; break; } - if(Direction >= 0) - { - Matrix4d m; - m.Init(Vector3d(), 0, Direction, 0); - Vector3d Look = m.Transform(Vector3d(0, 0, 1)); + m.Init(Vector3d(), 0, Direction, 0); + Look = m.Transform(Vector3d(0, 0, 1)); - Vector3d Speed = Look * 20; - Speed.y = Speed.y + 1; + Vector3d Angle = Look * 20; + Angle.y = Angle.y + 1; - return Speed; - - } else if(Direction == -1) - { - Matrix4d m; - m.Init(Vector3d(), 0, 180, 0); - Vector3d Look = m.Transform(Vector3d(0, 1, 0)); - - Vector3d Speed = Look * 20; - - return Speed; - - } else { - - Matrix4d m; - m.Init(Vector3d(), 0, -360, 0); - Vector3d Look = m.Transform(Vector3d(0, -1, 0)); - - Vector3d Speed = Look * 20; - - return Speed; - } + return Angle; } From 427bddc18970bb66aa1f396c4fd19e52e3ad602d Mon Sep 17 00:00:00 2001 From: JoannisO Date: Wed, 28 May 2014 15:16:45 +0200 Subject: [PATCH 148/312] - Removed breaks. I thought it wouldn't compile without them but the issue was appearantly solved with an earlier commit. --- src/BlockEntities/DispenserEntity.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 2b0487c4a..341994be8 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -223,14 +223,12 @@ Vector3d cDispenserEntity::GetProjectileLookVector(cChunk & a_Chunk) Look = m.Transform(Vector3d(0, 1, 0)); return Look * 20; // UP - break; case E_META_DROPSPENSER_FACING_YM: m.Init(Vector3d(), 0, -360, 0); Look = m.Transform(Vector3d(0, -1, 0)); return Look * 20;; // DOWN - break; case E_META_DROPSPENSER_FACING_XM: Direction = 90; break; // WEST case E_META_DROPSPENSER_FACING_XP: Direction = 270; break; // EAST From d29b242674fbf89035c8908753496522edf8eaee Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 28 May 2014 16:33:10 +0200 Subject: [PATCH 149/312] Fixed a memory leak in cPrefabPiecePool. The pool pieces weren't freed upon pool destruction. --- src/Generating/PrefabPiecePool.cpp | 28 ++++++++++++++++++++++++++++ src/Generating/PrefabPiecePool.h | 7 ++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Generating/PrefabPiecePool.cpp b/src/Generating/PrefabPiecePool.cpp index ed9340815..145474bcc 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); diff --git a/src/Generating/PrefabPiecePool.h b/src/Generating/PrefabPiecePool.h index c6a5ad360..50ae63c0c 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 */ From 7ec44951a0841734be53e81088dcdbc79a104d02 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 28 May 2014 11:35:55 +0200 Subject: [PATCH 150/312] Fixed cChunkData formatting. --- src/ChunkData.cpp | 118 +++++++++++++++++++++++++++++++++++----------- src/ChunkData.h | 22 ++++----- 2 files changed, 101 insertions(+), 39 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index c41dcb265..8aed62000 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -5,64 +5,86 @@ cChunkData::cChunkData() #if __cplusplus < 201103L // auto_ptr style interface for memory management - : IsOwner(true) + : m_IsOwner(true) #endif { - memset(m_Sections, 0, sizeof(m_Sections)); + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + m_Sections[i] = NULL; + } } + + + cChunkData::~cChunkData() { #if __cplusplus < 201103L // auto_ptr style interface for memory management - if (!IsOwner) + if (!m_IsOwner) { return; } #endif for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - if (m_Sections[i] == NULL) Free(m_Sections[i]);; + Free(m_Sections[i]); } } + + + + #if __cplusplus < 201103L // auto_ptr style interface for memory management - cChunkData::cChunkData(const cChunkData& other) : - IsOwner(true) + cChunkData::cChunkData(const cChunkData & a_Other) : + m_IsOwner(true) { + // Move contents and ownership from a_Other to this, pointer-wise: for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - m_Sections[i] = other.m_Sections[i]; + m_Sections[i] = a_Other.m_Sections[i]; } - other.IsOwner = false; + a_Other.m_IsOwner = false; } - cChunkData& cChunkData::operator=(const cChunkData& other) + + + + + cChunkData & cChunkData::operator =(const cChunkData & a_Other) { - if (&other != this) + // If assigning to self, no-op + if (&a_Other == this) + { + return *this; + } + + // Free any currently held contents: + if (m_IsOwner) { - if (IsOwner) - { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - if (m_Sections[i]) Free(m_Sections[i]);; - } - } - IsOwner = true; for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - m_Sections[i] = other.m_Sections[i]; + Free(m_Sections[i]); } - other.IsOwner = false; } + + // Move contents and ownership from a_Other to this, pointer-wise: + m_IsOwner = true; + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + m_Sections[i] = a_Other.m_Sections[i]; + } + a_Other.m_IsOwner = false; return *this; - } + #else + // unique_ptr style interface for memory management - cChunkData::cChunkData(cChunkData&& other) + cChunkData::cChunkData(cChunkData && other) { for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { @@ -70,14 +92,18 @@ cChunkData::~cChunkData() other.m_Sections[i] = NULL; } } + + + + - cChunkData& cChunkData::operator=(cChunkData&& other) + cChunkData & cChunkData::operator =(cChunkData && other) { if (&other != this) { for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - Free(m_Sections[i]);; + Free(m_Sections[i]); m_Sections[i] = other.m_Sections[i]; other.m_Sections[i] = NULL; } @@ -86,6 +112,10 @@ cChunkData::~cChunkData() } #endif + + + + BLOCKTYPE cChunkData::GetBlock(int a_X, int a_Y, int a_Z) const { ASSERT((a_X >= 0) && (a_X < cChunkDef::Width)); @@ -103,6 +133,10 @@ BLOCKTYPE cChunkData::GetBlock(int a_X, int a_Y, int a_Z) const } } + + + + void cChunkData::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block) { if ( @@ -134,6 +168,10 @@ void cChunkData::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block) m_Sections[Section]->m_BlockTypes[Index] = a_Block; } + + + + NIBBLETYPE cChunkData::GetMeta(int a_RelX, int a_RelY, int a_RelZ) const { if ( @@ -156,6 +194,10 @@ NIBBLETYPE cChunkData::GetMeta(int a_RelX, int a_RelY, int a_RelZ) const return 0; } + + + + bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble) { if ( @@ -192,9 +234,17 @@ bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble 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)) + 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 / CHUNK_SECTION_HEIGHT; if (m_Sections[Section] != NULL) @@ -211,6 +261,10 @@ NIBBLETYPE cChunkData::GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const 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)) @@ -230,7 +284,11 @@ NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const return 0; } -cChunkData cChunkData::Copy() const + + + + +cChunkData cChunkData::Copy(void) const { cChunkData copy; for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) @@ -248,11 +306,11 @@ cChunkData cChunkData::Copy() const -void cChunkData::CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx, size_t length) const +void cChunkData::CopyBlocks(BLOCKTYPE * a_dest, size_t a_Idx, size_t length) const { for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; + const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; if (a_Idx > 0) { a_Idx = std::max(a_Idx - length, (size_t) 0); @@ -588,6 +646,8 @@ cChunkData::sChunkSection * cChunkData::Allocate() const + + void cChunkData::Free(cChunkData::sChunkSection * ptr) const { delete ptr; @@ -595,6 +655,8 @@ void cChunkData::Free(cChunkData::sChunkSection * ptr) const + + void cChunkData::ZeroSection(cChunkData::sChunkSection * ptr) const { memset( diff --git a/src/ChunkData.h b/src/ChunkData.h index 16fcc4d37..6544b246e 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -25,12 +25,12 @@ public: #if __cplusplus < 201103L // auto_ptr style interface for memory management - cChunkData(const cChunkData& other); - cChunkData& operator=(const cChunkData& other); + cChunkData(const cChunkData & other); + cChunkData & operator =(const cChunkData & other); #else // unique_ptr style interface for memory management - cChunkData(cChunkData&& other); - cChunkData& operator=(cChunkData&& other); + cChunkData(cChunkData && other); + cChunkData & operator =(cChunkData && other); #endif BLOCKTYPE GetBlock(int a_X, int a_Y, int a_Z) const; @@ -43,15 +43,15 @@ public: NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; - cChunkData Copy() const; + cChunkData Copy(void) const; void CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx = 0, size_t length = cChunkDef::NumBlocks) const; void CopyMeta (NIBBLETYPE * a_dest) const; - void CopyBlockLight (NIBBLETYPE * a_dest) const; + void CopyBlockLight(NIBBLETYPE * a_dest) const; void CopySkyLight (NIBBLETYPE * a_dest) const; void SetBlocks (const BLOCKTYPE * a_src); void SetMeta (const NIBBLETYPE * a_src); - void SetBlockLight (const NIBBLETYPE * a_src); + void SetBlockLight(const NIBBLETYPE * a_src); void SetSkyLight (const NIBBLETYPE * a_src); private: @@ -61,19 +61,19 @@ private: #if __cplusplus < 201103L // auto_ptr style interface for memory management - mutable bool IsOwner; + mutable bool m_IsOwner; #endif struct sChunkSection { - BLOCKTYPE m_BlockTypes [CHUNK_SECTION_HEIGHT * 16 * 16] ; + BLOCKTYPE m_BlockTypes [CHUNK_SECTION_HEIGHT * 16 * 16]; NIBBLETYPE m_BlockMeta [CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; NIBBLETYPE m_BlockLight [CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; NIBBLETYPE m_BlockSkyLight[CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; }; - sChunkSection *m_Sections[CHUNK_SECTION_COUNT]; + sChunkSection * m_Sections[CHUNK_SECTION_COUNT]; - sChunkSection * Allocate() const; + sChunkSection * Allocate(void) const; void Free(sChunkSection * ptr) const; void ZeroSection(sChunkSection * ptr) const; From 171e13de4f58cdc4f8a97cd8adfbfbfbcf1df615 Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 28 May 2014 15:59:59 +0100 Subject: [PATCH 151/312] for compiliers other than msvc we need to tell lua that its building as a dll --- lib/lua/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) 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) From 1cf426d881e1ea3dbfae5ebae701e02cd41c95a0 Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 28 May 2014 20:39:47 +0100 Subject: [PATCH 152/312] FreeBSD requires __POSIX_VISIBLE macro to be defined --- lib/sqlite/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/sqlite/CMakeLists.txt b/lib/sqlite/CMakeLists.txt index 0815127ef..d3bba6606 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 (SYSTEM_NAME STREQUAL "FreeBSD")) + add_flags_cxx(-D__POSIX_VISIBLE=200112) +endif() add_library(sqlite ${SOURCE}) From a2b741d904d55915fe041ff17d2ffadc7bf8221c Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 28 May 2014 20:41:34 +0100 Subject: [PATCH 153/312] derp --- lib/sqlite/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sqlite/CMakeLists.txt b/lib/sqlite/CMakeLists.txt index d3bba6606..da16ce411 100644 --- a/lib/sqlite/CMakeLists.txt +++ b/lib/sqlite/CMakeLists.txt @@ -18,7 +18,7 @@ if (WIN32) endif() # FreeBSD requires us to define this to get POSIX 2001 standard -if (SYSTEM_NAME STREQUAL "FreeBSD")) +if (SYSTEM_NAME STREQUAL "FreeBSD") add_flags_cxx(-D__POSIX_VISIBLE=200112) endif() From 444cce1269b3efc3370358b389c4ebdfe1f2e5b2 Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 28 May 2014 21:39:28 +0100 Subject: [PATCH 154/312] Cmake system name not System name --- lib/sqlite/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sqlite/CMakeLists.txt b/lib/sqlite/CMakeLists.txt index da16ce411..9add2280b 100644 --- a/lib/sqlite/CMakeLists.txt +++ b/lib/sqlite/CMakeLists.txt @@ -18,7 +18,7 @@ if (WIN32) endif() # FreeBSD requires us to define this to get POSIX 2001 standard -if (SYSTEM_NAME STREQUAL "FreeBSD") +if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") add_flags_cxx(-D__POSIX_VISIBLE=200112) endif() From 81f756cbda76507cc676fd50f20f33483c4ce6f8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 28 May 2014 22:40:19 +0200 Subject: [PATCH 155/312] cChunkData: Normalized code style. --- src/ChunkData.cpp | 168 +++++++++++++++++++++++++--------------------- src/ChunkData.h | 27 +++++--- 2 files changed, 106 insertions(+), 89 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 8aed62000..beee6c64a 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -306,33 +306,33 @@ cChunkData cChunkData::Copy(void) const -void cChunkData::CopyBlocks(BLOCKTYPE * a_dest, size_t a_Idx, size_t length) const +void cChunkData::CopyBlocks(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const { for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; + const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16; if (a_Idx > 0) { - a_Idx = std::max(a_Idx - length, (size_t) 0); + a_Idx = std::max(a_Idx - a_Length, (size_t) 0); } if (a_Idx == 0) { - size_t tocopy = std::min(segment_length, length); - length -= tocopy; + size_t ToCopy = std::min(SegmentLength, a_Length); + length -= ToCopy; if (m_Sections[i] != NULL) { memcpy( - &a_dest[i * segment_length], + &a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockTypes, - sizeof(BLOCKTYPE) * tocopy + sizeof(BLOCKTYPE) * ToCopy ); } else { memset( - &a_dest[i * segment_length], + &a_Dest[i * SegmentLength], 0, - sizeof(BLOCKTYPE) * tocopy + sizeof(BLOCKTYPE) * ToCopy ); } } @@ -343,25 +343,25 @@ void cChunkData::CopyBlocks(BLOCKTYPE * a_dest, size_t a_Idx, size_t length) co -void cChunkData::CopyMeta(NIBBLETYPE * a_dest) const +void cChunkData::CopyMeta(NIBBLETYPE * a_Dest) const { for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) { memcpy( - &a_dest[i * segment_length], + &a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockMeta, - sizeof(NIBBLETYPE) * segment_length + sizeof(NIBBLETYPE) * SegmentLength ); } else { memset( - &a_dest[i * segment_length], + &a_Dest[i * SegmentLength], 0, - sizeof(BLOCKTYPE) * segment_length + sizeof(BLOCKTYPE) * SegmentLength ); } } @@ -371,25 +371,25 @@ void cChunkData::CopyMeta(NIBBLETYPE * a_dest) const -void cChunkData::CopyBlockLight(NIBBLETYPE * a_dest) const +void cChunkData::CopyBlockLight(NIBBLETYPE * a_Dest) const { for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) { memcpy( - &a_dest[i * segment_length], + &a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockLight, - sizeof(NIBBLETYPE) * segment_length + sizeof(NIBBLETYPE) * SegmentLength ); } else { memset( - &a_dest[i * segment_length], + &a_Dest[i * SegmentLength], 0, - sizeof(BLOCKTYPE) * segment_length + sizeof(BLOCKTYPE) * SegmentLength ); } } @@ -399,25 +399,25 @@ void cChunkData::CopyBlockLight(NIBBLETYPE * a_dest) const -void cChunkData::CopySkyLight(NIBBLETYPE * a_dest) const +void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const { for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) { memcpy( - &a_dest[i * segment_length], + &a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockSkyLight, - sizeof(NIBBLETYPE) * segment_length + sizeof(NIBBLETYPE) * SegmentLength ); } else { memset( - &a_dest[i * segment_length], + &a_Dest[i * SegmentLength], 0xFF, - sizeof(BLOCKTYPE) * segment_length + sizeof(BLOCKTYPE) * SegmentLength ); } } @@ -427,34 +427,36 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_dest) const -void cChunkData::SetBlocks(const BLOCKTYPE * a_src) +void cChunkData::SetBlocks(const BLOCKTYPE * a_Src) { + ASSERT(a_Src != NULL); + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16; + const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16; if (m_Sections[i] != NULL) { memcpy( &m_Sections[i]->m_BlockTypes, - &a_src[i * segment_length], - sizeof(BLOCKTYPE) * segment_length + &a_Src[i * SegmentLength], + sizeof(BLOCKTYPE) * SegmentLength ); } else { // j counts how many of leading zeros the buffer has - // if j == segment_length then the buffer is all zeros so there is no point + // if j == SegmentLength then the buffer is all zeros so there is no point // creating the buffer. size_t j = 0; // do nothing whilst 0 - for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); - if (j != segment_length) + for (; (j < SegmentLength) && (a_Src[i * SegmentLength + j] == 0); j++); + if (j != SegmentLength) { m_Sections[i] = Allocate(); memcpy( &m_Sections[i]->m_BlockTypes, - &a_src[i * segment_length], - sizeof(BLOCKTYPE) * segment_length + &a_Src[i * SegmentLength], + sizeof(BLOCKTYPE) * SegmentLength ); memset( m_Sections[i]->m_BlockMeta, @@ -479,34 +481,36 @@ void cChunkData::SetBlocks(const BLOCKTYPE * a_src) -void cChunkData::SetMeta(const NIBBLETYPE * a_src) +void cChunkData::SetMeta(const NIBBLETYPE * a_Src) { + ASSERT(a_Src != NULL); + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) { memcpy( &m_Sections[i]->m_BlockMeta, - &a_src[i * segment_length], - sizeof(NIBBLETYPE) * segment_length + &a_Src[i * SegmentLength], + sizeof(NIBBLETYPE) * SegmentLength ); } else { // j counts how many of leading zeros the buffer has - // if j == segment_length then the buffer is all zeros so there is no point + // if j == SegmentLength then the buffer is all zeros so there is no point // creating the buffer. size_t j = 0; // do nothing whilst 0 - for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); - if (j != segment_length) + for (; (j < SegmentLength) && (a_Src[i * SegmentLength + j] == 0); j++); + if (j != SegmentLength) { m_Sections[i] = Allocate(); memcpy( &m_Sections[i]->m_BlockMeta, - &a_src[i * segment_length], - sizeof(BLOCKTYPE) * segment_length + &a_Src[i * SegmentLength], + sizeof(BLOCKTYPE) * SegmentLength ); memset( m_Sections[i]->m_BlockTypes, @@ -531,35 +535,38 @@ void cChunkData::SetMeta(const NIBBLETYPE * a_src) -void cChunkData::SetBlockLight(const NIBBLETYPE * a_src) +void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) { - if (!a_src) return; + if (a_Src == NULL) + { + return; + } for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) { memcpy( &m_Sections[i]->m_BlockLight, - &a_src[i * segment_length], - sizeof(NIBBLETYPE) * segment_length + &a_Src[i * SegmentLength], + sizeof(NIBBLETYPE) * SegmentLength ); } else { // j counts how many of leading zeros the buffer has - // if j == segment_length then the buffer is all zeros so there is no point + // if j == SegmentLength then the buffer is all zeros so there is no point // creating the buffer. size_t j = 0; // do nothing whilst 0 - for (; j < segment_length && a_src[i * segment_length + j] == 0; j++); - if (j != segment_length) + for (; (j < SegmentLength) && (a_Src[i * SegmentLength + j] == 0); j++); + if (j != SegmentLength) { m_Sections[i] = Allocate(); memcpy( &m_Sections[i]->m_BlockLight, - &a_src[i * segment_length], - sizeof(BLOCKTYPE) * segment_length + &a_Src[i * SegmentLength], + sizeof(BLOCKTYPE) * SegmentLength ); memset( m_Sections[i]->m_BlockTypes, @@ -584,35 +591,39 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_src) -void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) +void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) { - if (!a_src) return; + if (a_Src == NULL) + { + return; + } + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) { - const size_t segment_length = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; if (m_Sections[i] != NULL) { memcpy( &m_Sections[i]->m_BlockSkyLight, - &a_src[i * segment_length], - sizeof(NIBBLETYPE) * segment_length + &a_Src[i * SegmentLength], + sizeof(NIBBLETYPE) * SegmentLength ); } else { // j counts how many of leading zeros the buffer has - // if j == segment_length then the buffer is all zeros so there is no point + // if j == SegmentLength then the buffer is all zeros so there is no point // creating the buffer. size_t j = 0; // do nothing whilst 0 - for (; j < segment_length && a_src[i * segment_length + j] == 0xFF; j++); - if (j != segment_length) + for (; (j < SegmentLength) && (a_Src[i * SegmentLength + j]) == 0xFF; j++); + if (j != SegmentLength) { m_Sections[i] = Allocate(); memcpy( &m_Sections[i]->m_BlockSkyLight, - &a_src[i * segment_length], - sizeof(BLOCKTYPE) * segment_length + &a_Src[i * SegmentLength], + sizeof(BLOCKTYPE) * SegmentLength ); memset( m_Sections[i]->m_BlockTypes, @@ -638,9 +649,9 @@ void cChunkData::SetSkyLight (const NIBBLETYPE * a_src) -cChunkData::sChunkSection * cChunkData::Allocate() const +cChunkData::sChunkSection * cChunkData::Allocate(void) const { - // TODO: use a allocation pool + // TODO: Use an allocation pool return new cChunkData::sChunkSection; } @@ -648,36 +659,37 @@ cChunkData::sChunkSection * cChunkData::Allocate() const -void cChunkData::Free(cChunkData::sChunkSection * ptr) const +void cChunkData::Free(cChunkData::sChunkSection * a_Section) const { - delete ptr; + // TODO: Use an allocation pool + delete a_Section; } -void cChunkData::ZeroSection(cChunkData::sChunkSection * ptr) const +void cChunkData::ZeroSection(cChunkData::sChunkSection * a_Section) const { memset( - ptr->m_BlockTypes, + a_Section->m_BlockTypes, 0x00, - sizeof(ptr->m_BlockTypes) + sizeof(a_Section->m_BlockTypes) ); memset( - ptr->m_BlockMeta, + a_Section->m_BlockMeta, 0x00, - sizeof(ptr->m_BlockMeta) + sizeof(a_Section->m_BlockMeta) ); memset( - ptr->m_BlockLight, + a_Section->m_BlockLight, 0x00, - sizeof(ptr->m_BlockLight) + sizeof(a_Section->m_BlockLight) ); memset( - ptr->m_BlockSkyLight, + a_Section->m_BlockSkyLight, 0xFF, - sizeof(ptr->m_BlockSkyLight) + sizeof(a_Section->m_BlockSkyLight) ); } diff --git a/src/ChunkData.h b/src/ChunkData.h index 6544b246e..09b2cb563 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -25,12 +25,12 @@ public: #if __cplusplus < 201103L // auto_ptr style interface for memory management - cChunkData(const cChunkData & other); - cChunkData & operator =(const cChunkData & other); + cChunkData(const cChunkData & a_Other); + cChunkData & operator =(const cChunkData & a_Other); #else // unique_ptr style interface for memory management - cChunkData(cChunkData && other); - cChunkData & operator =(cChunkData && other); + cChunkData(cChunkData && a_Other); + cChunkData & operator =(cChunkData && a_ther); #endif BLOCKTYPE GetBlock(int a_X, int a_Y, int a_Z) const; @@ -44,10 +44,10 @@ public: NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; cChunkData Copy(void) const; - void CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx = 0, size_t length = cChunkDef::NumBlocks) const; - void CopyMeta (NIBBLETYPE * a_dest) const; - void CopyBlockLight(NIBBLETYPE * a_dest) const; - void CopySkyLight (NIBBLETYPE * a_dest) const; + void CopyBlocks (BLOCKTYPE * a_Dest, size_t a_Idx = 0, size_t a_Length = cChunkDef::NumBlocks) const; + void CopyMeta (NIBBLETYPE * a_Dest) const; + void CopyBlockLight(NIBBLETYPE * a_Dest) const; + void CopySkyLight (NIBBLETYPE * a_Dest) const; void SetBlocks (const BLOCKTYPE * a_src); void SetMeta (const NIBBLETYPE * a_src); @@ -73,10 +73,15 @@ private: sChunkSection * m_Sections[CHUNK_SECTION_COUNT]; - sChunkSection * Allocate(void) const; - void Free(sChunkSection * ptr) const; + /** Allocates a new section. Entry-point to custom allocators. */ + static sChunkSection * Allocate(void); - void ZeroSection(sChunkSection * ptr) const; + /** Frees the specified section, previously allocated using Allocate(). + Note that a_Section may be NULL. */ + static void Free(sChunkSection * a_Section); + + /** Sets the data in the specified section to their default values. */ + void ZeroSection(sChunkSection * a_Section) const; }; From 10273f64a2ec326201d3553f3704d2d6f21b7a86 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 28 May 2014 22:41:23 +0200 Subject: [PATCH 156/312] Fixed a crash in message formatter. The code would fail if a message is sent to a player not yet added to a world. --- src/Protocol/Protocol17x.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 7c526d103..f7564fe6d 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -234,7 +234,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) { From 999662503a90e6acd4528be50f8b6232b357d9c3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 29 May 2014 09:09:11 +0200 Subject: [PATCH 157/312] Fixed forgotten changes. --- src/ChunkData.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index beee6c64a..172858e4e 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -318,7 +318,7 @@ void cChunkData::CopyBlocks(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) if (a_Idx == 0) { size_t ToCopy = std::min(SegmentLength, a_Length); - length -= ToCopy; + a_Length -= ToCopy; if (m_Sections[i] != NULL) { memcpy( @@ -649,7 +649,7 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) -cChunkData::sChunkSection * cChunkData::Allocate(void) const +cChunkData::sChunkSection * cChunkData::Allocate(void) { // TODO: Use an allocation pool return new cChunkData::sChunkSection; @@ -659,7 +659,7 @@ cChunkData::sChunkSection * cChunkData::Allocate(void) const -void cChunkData::Free(cChunkData::sChunkSection * a_Section) const +void cChunkData::Free(cChunkData::sChunkSection * a_Section) { // TODO: Use an allocation pool delete a_Section; From e5187aa645b0f06e58e347bed1f8d68916764ba1 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 29 May 2014 09:19:20 +0200 Subject: [PATCH 158/312] Fixed a memory leak in cPOCPieceGenerator --- src/Generating/POCPieceGenerator.cpp | 5 +++++ 1 file changed, 5 insertions(+) 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(); } From ae4371a733ee3ac029498ddef50850cc0ca9cbd9 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 May 2014 11:56:22 +0100 Subject: [PATCH 159/312] Fixed piston power checking --- src/Simulator/IncrementalRedstoneSimulator.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index c24b1c4b3..51a7c2886 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -1489,41 +1489,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 = cBlockPistonHandler::MetaDataToDirection(a_Meta); - int BlockX = (m_Chunk->GetPosX() * cChunkDef::Width) + a_RelBlockX; - int BlockZ = (m_Chunk->GetPosZ() * cChunkDef::Width) + a_RelBlockZ; + 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 } From 365c6f50bd057eb62c66b9b222a07ca6efcb2c47 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 May 2014 11:57:06 +0100 Subject: [PATCH 160/312] Changed block send queue to use vectors As suggested by @worktycho. --- src/Blocks/BlockPiston.cpp | 23 +++++++++++++++++------ src/World.cpp | 21 ++++++++++----------- src/World.h | 6 ++---- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index f758013dc..1f8e0d9e0 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -27,6 +27,7 @@ } #define PISTON_TICK_DELAY 1 +#define PISTON_MAX_PUSH_DISTANCE 12 @@ -78,7 +79,7 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( int cBlockPistonHandler::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, NIBBLETYPE pistonmeta, cWorld * a_World) { // Examine each of the 12 blocks ahead of the piston: - for (int ret = 0; ret < 12; ret++) + for (int ret = 0; ret < PISTON_MAX_PUSH_DISTANCE; ret++) { BLOCKTYPE currBlock; NIBBLETYPE currMeta; @@ -144,12 +145,15 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, // Push blocks, from the furthest to the nearest: int oldx = a_BlockX, oldy = a_BlockY, oldz = a_BlockZ; NIBBLETYPE currBlockMeta; + std::vector 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); - a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(oldx, oldy, oldz)); + ScheduledBlocks.push_back(Vector3i(oldx, oldy, oldz)); oldx = a_BlockX; oldy = a_BlockY; oldz = a_BlockZ; @@ -158,12 +162,13 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int 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(extx, exty, extz)); + a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(ScheduledBlocks)); } @@ -209,15 +214,21 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ // 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); - a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(a_BlockX, a_BlockY, a_BlockZ)); - a_World->ScheduleTask(PISTON_TICK_DELAY, new cWorld::cTaskSendBlockToAllPlayers(tempx, tempy, tempz)); + + std::vector 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); - a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(a_BlockX, a_BlockY, a_BlockZ)); + + std::vector ScheduledBlocks; + ScheduledBlocks.push_back(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); + a_World->ScheduleTask(PISTON_TICK_DELAY + 1, new cWorld::cTaskSendBlockToAllPlayers(ScheduledBlocks)); } diff --git a/src/World.cpp b/src/World.cpp index 29046bba9..88e9c32e6 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3130,10 +3130,8 @@ void cWorld::cTaskUnloadUnusedChunks::Run(cWorld & a_World) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cWorld::cTaskSendBlockTo -cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(int a_BlockX, int a_BlockY, int a_BlockZ) : - m_BlockX(a_BlockX), - m_BlockY(a_BlockY), - m_BlockZ(a_BlockZ) +cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(std::vector & a_SendQueue) : + m_SendQueue(a_SendQueue) { } @@ -3143,26 +3141,27 @@ void cWorld::cTaskSendBlockToAllPlayers::Run(cWorld & a_World) public cPlayerListCallback { public: - cPlayerCallback(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld & a_World) : - m_BlockX(a_BlockX), - m_BlockY(a_BlockY), - m_BlockZ(a_BlockZ), + cPlayerCallback(std::vector & a_SendQueue, cWorld & a_World) : + m_SendQueue(a_SendQueue), m_World(a_World) { } virtual bool Item(cPlayer * a_Player) { - m_World.SendBlockTo(m_BlockX, m_BlockY, m_BlockZ, a_Player); + for (std::vector::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: - int m_BlockX, m_BlockY, m_BlockZ; + std::vector m_SendQueue; cWorld & m_World; - } PlayerCallback(m_BlockX, m_BlockY, m_BlockZ, a_World); + } PlayerCallback(m_SendQueue, a_World); a_World.ForEachPlayer(PlayerCallback); } diff --git a/src/World.h b/src/World.h index 5ef63a540..98b241a2b 100644 --- a/src/World.h +++ b/src/World.h @@ -121,15 +121,13 @@ public: public cTask { public: - cTaskSendBlockToAllPlayers(int a_BlockX, int a_BlockY, int a_BlockZ); + cTaskSendBlockToAllPlayers(std::vector & a_SendQueue); protected: // cTask overrides: virtual void Run(cWorld & a_World) override; - int m_BlockX; - int m_BlockY; - int m_BlockZ; + std::vector m_SendQueue; }; From d9c667d28f556e489b2779b7510f3b12034c3fad Mon Sep 17 00:00:00 2001 From: worktycho Date: Thu, 29 May 2014 12:04:37 +0100 Subject: [PATCH 161/312] Add comment --- src/ChunkData.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ChunkData.h b/src/ChunkData.h index 09b2cb563..e6aaa99b8 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -44,6 +44,10 @@ public: NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; cChunkData Copy(void) const; + + // Copys data from this object into the buffer in the a_Dest param + // CopyBlocks also povides the optional parameters a_Idx and a_Length which specify an offset and length for + // copying part of the BlockTypes array. void CopyBlocks (BLOCKTYPE * a_Dest, size_t a_Idx = 0, size_t a_Length = cChunkDef::NumBlocks) const; void CopyMeta (NIBBLETYPE * a_Dest) const; void CopyBlockLight(NIBBLETYPE * a_Dest) const; From bacc873a175cb37a1878fccf8fa40acb75fb8189 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 May 2014 12:12:10 +0100 Subject: [PATCH 162/312] Revert "Fixed a food saturation issue" This reverts commit 67308e4337b422ebefb249049e662266072b0ba2. --- src/Entities/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 1e1e868e7..0eacb67f9 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -551,7 +551,7 @@ bool cPlayer::Feed(int a_Food, double a_Saturation) } m_FoodLevel = std::min(a_Food + m_FoodLevel, (int)MAX_FOOD_LEVEL); - m_FoodSaturationLevel = m_FoodSaturationLevel + a_Saturation; + m_FoodSaturationLevel = std::min(m_FoodSaturationLevel + a_Saturation, (double)m_FoodLevel); SendHealth(); return true; From 3549d0d5e6e99342f3422396ac80b66c3e3d54db Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 May 2014 15:59:39 +0100 Subject: [PATCH 163/312] More comments! --- src/Chunk.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 6bd68459c..fbd0a5846 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1587,11 +1587,10 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT } m_BlockTypes[index] = a_BlockType; - // The client doesn't need to distinguish between stationary and nonstationary fluids: - if ( - a_SendToClients && - ((OldBlockMeta != a_BlockMeta) || // Different meta always gets sent to the client - !( + 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 From aa4477822ab0f1cdba904fd39e065bf8e86f9aec Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 May 2014 16:03:41 +0100 Subject: [PATCH 164/312] Suggestions --- src/Blocks/BlockPiston.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index d7c92925b..e6fa48e54 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -143,7 +143,12 @@ private: } } - return CanBreakPush(a_BlockType) ? false /* CanBreakPush returns true, but we need false to prevent pulling */ : CanPush(a_BlockType, a_BlockMeta); + 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 From f7777e8c7559964f126a64af7673276e356dcedc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 29 May 2014 18:25:08 +0200 Subject: [PATCH 165/312] Added comments, reformatted code. --- src/BlockArea.cpp | 2 +- src/Chunk.cpp | 6 +- src/ChunkData.cpp | 391 +++++++++++++++------------------------- src/ChunkData.h | 65 +++++-- src/ChunkDataCallback.h | 40 +++- src/LightingThread.cpp | 2 +- 6 files changed, 226 insertions(+), 280 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 11bd76e6c..40fdd68c0 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -1903,7 +1903,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) if (m_Area.m_BlockMetas != NULL) { - a_BlockBuffer.CopyMeta(m_Area.m_BlockMetas); + a_BlockBuffer.CopyMetas(m_Area.m_BlockMetas); } if (m_Area.m_BlockLight != NULL) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index e5f8f1e29..23412a4c3 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -282,8 +282,8 @@ void cChunk::SetAllData( CalculateHeightmap(a_BlockTypes); } - m_ChunkData.SetBlocks(a_BlockTypes); - m_ChunkData.SetMeta(a_BlockMeta); + m_ChunkData.SetBlockTypes(a_BlockTypes); + m_ChunkData.SetMetas(a_BlockMeta); m_ChunkData.SetBlockLight(a_BlockLight); m_ChunkData.SetSkyLight(a_BlockSkyLight); @@ -339,7 +339,7 @@ void cChunk::SetLight( void cChunk::GetBlockTypes(BLOCKTYPE * a_BlockTypes) { - m_ChunkData.CopyBlocks(a_BlockTypes); + m_ChunkData.CopyBlockTypes(a_BlockTypes); } diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 172858e4e..cc4793ec3 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -1,14 +1,39 @@ +// 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" -cChunkData::cChunkData() + + + + +/** Returns true if all a_Array's elements between [0] and [a_NumElements - 1] are equal to a_Value. */ +template 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(void) #if __cplusplus < 201103L // auto_ptr style interface for memory management : m_IsOwner(true) #endif { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { m_Sections[i] = NULL; } @@ -27,7 +52,7 @@ cChunkData::~cChunkData() return; } #endif - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { Free(m_Sections[i]); } @@ -43,7 +68,7 @@ cChunkData::~cChunkData() m_IsOwner(true) { // Move contents and ownership from a_Other to this, pointer-wise: - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { m_Sections[i] = a_Other.m_Sections[i]; } @@ -65,7 +90,7 @@ cChunkData::~cChunkData() // Free any currently held contents: if (m_IsOwner) { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { Free(m_Sections[i]); } @@ -73,7 +98,7 @@ cChunkData::~cChunkData() // Move contents and ownership from a_Other to this, pointer-wise: m_IsOwner = true; - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { m_Sections[i] = a_Other.m_Sections[i]; } @@ -86,7 +111,7 @@ cChunkData::~cChunkData() // unique_ptr style interface for memory management cChunkData::cChunkData(cChunkData && other) { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { m_Sections[i] = other.m_Sections[i]; other.m_Sections[i] = NULL; @@ -101,7 +126,7 @@ cChunkData::~cChunkData() { if (&other != this) { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { Free(m_Sections[i]); m_Sections[i] = other.m_Sections[i]; @@ -121,10 +146,10 @@ 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 / CHUNK_SECTION_HEIGHT; + int Section = a_Y / SectionHeight; if (m_Sections[Section] != NULL) { - int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * CHUNK_SECTION_HEIGHT), a_Z); + int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * SectionHeight), a_Z); return m_Sections[Section]->m_BlockTypes[Index]; } else @@ -149,7 +174,7 @@ void cChunkData::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block) return; } - int Section = a_RelY / CHUNK_SECTION_HEIGHT; + int Section = a_RelY / SectionHeight; if (m_Sections[Section] == NULL) { if (a_Block == 0x00) @@ -164,7 +189,7 @@ void cChunkData::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block) } ZeroSection(m_Sections[Section]); } - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ); m_Sections[Section]->m_BlockTypes[Index] = a_Block; } @@ -179,10 +204,10 @@ NIBBLETYPE cChunkData::GetMeta(int a_RelX, int a_RelY, int a_RelZ) const (a_RelY < cChunkDef::Height) && (a_RelY > -1) && (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)) { - int Section = a_RelY / CHUNK_SECTION_HEIGHT; + int Section = a_RelY / SectionHeight; if (m_Sections[Section] != NULL) { - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ); return (m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4)) & 0x0f; } else @@ -210,7 +235,7 @@ bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble return false; } - int Section = a_RelY / CHUNK_SECTION_HEIGHT; + int Section = a_RelY / SectionHeight; if (m_Sections[Section] == NULL) { if ((a_Nibble & 0xf) == 0x00) @@ -225,7 +250,7 @@ bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble } ZeroSection(m_Sections[Section]); } - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ); NIBBLETYPE oldval = m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4) & 0xf; m_Sections[Section]->m_BlockMeta[Index / 2] = static_cast( (m_Sections[Section]->m_BlockMeta[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble @@ -246,10 +271,10 @@ NIBBLETYPE cChunkData::GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const (a_RelZ < cChunkDef::Width) && (a_RelZ > -1) ) { - int Section = a_RelY / CHUNK_SECTION_HEIGHT; + int Section = a_RelY / SectionHeight; if (m_Sections[Section] != NULL) { - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + 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 @@ -269,10 +294,10 @@ 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 / CHUNK_SECTION_HEIGHT; + int Section = a_RelY / SectionHeight; if (m_Sections[Section] != NULL) { - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + 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 @@ -291,7 +316,7 @@ NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const cChunkData cChunkData::Copy(void) const { cChunkData copy; - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { if (m_Sections[i] != NULL) { @@ -306,11 +331,12 @@ cChunkData cChunkData::Copy(void) const -void cChunkData::CopyBlocks(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const +void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + // TODO: This code seems wrong. It always copies into a_Dest[i * SegmentLength], even when a_Idx > 0 + for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16; + const size_t SegmentLength = SectionHeight * 16 * 16; if (a_Idx > 0) { a_Idx = std::max(a_Idx - a_Length, (size_t) 0); @@ -321,19 +347,11 @@ void cChunkData::CopyBlocks(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) a_Length -= ToCopy; if (m_Sections[i] != NULL) { - memcpy( - &a_Dest[i * SegmentLength], - &m_Sections[i]->m_BlockTypes, - sizeof(BLOCKTYPE) * ToCopy - ); + memcpy(&a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockTypes, sizeof(BLOCKTYPE) * ToCopy); } else { - memset( - &a_Dest[i * SegmentLength], - 0, - sizeof(BLOCKTYPE) * ToCopy - ); + memset(&a_Dest[i * SegmentLength], 0, sizeof(BLOCKTYPE) * ToCopy); } } } @@ -343,26 +361,18 @@ void cChunkData::CopyBlocks(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) -void cChunkData::CopyMeta(NIBBLETYPE * a_Dest) const +void cChunkData::CopyMetas(NIBBLETYPE * a_Dest) const { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t SegmentLength = SectionHeight * 16 * 16 / 2; if (m_Sections[i] != NULL) { - memcpy( - &a_Dest[i * SegmentLength], - &m_Sections[i]->m_BlockMeta, - sizeof(NIBBLETYPE) * SegmentLength - ); + memcpy(&a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockMeta, sizeof(NIBBLETYPE) * SegmentLength); } else { - memset( - &a_Dest[i * SegmentLength], - 0, - sizeof(BLOCKTYPE) * SegmentLength - ); + memset(&a_Dest[i * SegmentLength], 0, sizeof(BLOCKTYPE) * SegmentLength); } } } @@ -373,24 +383,16 @@ void cChunkData::CopyMeta(NIBBLETYPE * a_Dest) const void cChunkData::CopyBlockLight(NIBBLETYPE * a_Dest) const { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t SegmentLength = SectionHeight * 16 * 16 / 2; if (m_Sections[i] != NULL) { - memcpy( - &a_Dest[i * SegmentLength], - &m_Sections[i]->m_BlockLight, - sizeof(NIBBLETYPE) * SegmentLength - ); + memcpy(&a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockLight, sizeof(NIBBLETYPE) * SegmentLength); } else { - memset( - &a_Dest[i * SegmentLength], - 0, - sizeof(BLOCKTYPE) * SegmentLength - ); + memset(&a_Dest[i * SegmentLength], 0, sizeof(BLOCKTYPE) * SegmentLength); } } } @@ -401,24 +403,16 @@ void cChunkData::CopyBlockLight(NIBBLETYPE * a_Dest) const void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + const size_t SegmentLength = SectionHeight * 16 * 16 / 2; if (m_Sections[i] != NULL) { - memcpy( - &a_Dest[i * SegmentLength], - &m_Sections[i]->m_BlockSkyLight, - sizeof(NIBBLETYPE) * SegmentLength - ); + memcpy(&a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockSkyLight, sizeof(NIBBLETYPE) * SegmentLength); } else { - memset( - &a_Dest[i * SegmentLength], - 0xFF, - sizeof(BLOCKTYPE) * SegmentLength - ); + memset(&a_Dest[i * SegmentLength], 0xff, sizeof(BLOCKTYPE) * SegmentLength); } } } @@ -427,165 +421,102 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const -void cChunkData::SetBlocks(const BLOCKTYPE * a_Src) +void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) { ASSERT(a_Src != NULL); - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + static const size_t SegmentLength = SectionHeight * 16 * 16; + for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16; + // 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 * SegmentLength], - sizeof(BLOCKTYPE) * SegmentLength - ); + memcpy(&m_Sections[i]->m_BlockTypes, &a_Src[i * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); + continue; } - else + + // The section doesn't exist, find out if it is needed: + if (IsAllValue(a_Src + i * SegmentLength, SegmentLength, (const BLOCKTYPE)0)) { - // j counts how many of leading zeros the buffer has - // if j == SegmentLength then the buffer is all zeros so there is no point - // creating the buffer. - size_t j = 0; - // do nothing whilst 0 - for (; (j < SegmentLength) && (a_Src[i * SegmentLength + j] == 0); j++); - if (j != SegmentLength) - { - m_Sections[i] = Allocate(); - memcpy( - &m_Sections[i]->m_BlockTypes, - &a_Src[i * SegmentLength], - sizeof(BLOCKTYPE) * SegmentLength - ); - memset( - m_Sections[i]->m_BlockMeta, - 0x00, - sizeof(m_Sections[i]->m_BlockMeta) - ); - 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) - ); - } + // 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 * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); + memset(m_Sections[i]->m_BlockMeta, 0x00, sizeof(m_Sections[i]->m_BlockMeta)); + 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::SetMeta(const NIBBLETYPE * a_Src) +void cChunkData::SetMetas(const NIBBLETYPE * a_Src) { ASSERT(a_Src != NULL); - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + // If the section is already allocated, copy the data into it: if (m_Sections[i] != NULL) { - memcpy( - &m_Sections[i]->m_BlockMeta, - &a_Src[i * SegmentLength], - sizeof(NIBBLETYPE) * SegmentLength - ); + memcpy(&m_Sections[i]->m_BlockMeta, &a_Src[i * SegmentLength], sizeof(NIBBLETYPE) * SegmentLength); + continue; } - else + + // The section doesn't exist, find out if it is needed: + if (IsAllValue(a_Src + i * SegmentLength, SegmentLength, (NIBBLETYPE)0)) { - // j counts how many of leading zeros the buffer has - // if j == SegmentLength then the buffer is all zeros so there is no point - // creating the buffer. - size_t j = 0; - // do nothing whilst 0 - for (; (j < SegmentLength) && (a_Src[i * SegmentLength + j] == 0); j++); - if (j != SegmentLength) - { - m_Sections[i] = Allocate(); - memcpy( - &m_Sections[i]->m_BlockMeta, - &a_Src[i * SegmentLength], - sizeof(BLOCKTYPE) * SegmentLength - ); - 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) - ); - } + // 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_BlockMeta, &a_Src[i * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); + 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 < CHUNK_SECTION_COUNT; i++) + + for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + // 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 * SegmentLength], - sizeof(NIBBLETYPE) * SegmentLength - ); + memcpy(&m_Sections[i]->m_BlockLight, &a_Src[i * SegmentLength], sizeof(NIBBLETYPE) * SegmentLength); + continue; } - else + + // The section doesn't exist, find out if it is needed: + if (IsAllValue(a_Src + i * SegmentLength, SegmentLength, (NIBBLETYPE)0)) { - // j counts how many of leading zeros the buffer has - // if j == SegmentLength then the buffer is all zeros so there is no point - // creating the buffer. - size_t j = 0; - // do nothing whilst 0 - for (; (j < SegmentLength) && (a_Src[i * SegmentLength + j] == 0); j++); - if (j != SegmentLength) - { - m_Sections[i] = Allocate(); - memcpy( - &m_Sections[i]->m_BlockLight, - &a_Src[i * SegmentLength], - sizeof(BLOCKTYPE) * SegmentLength - ); - memset( - m_Sections[i]->m_BlockTypes, - 0x00, - sizeof(m_Sections[i]->m_BlockTypes) - ); - memset( - m_Sections[i]->m_BlockMeta, - 0x00, - sizeof(m_Sections[i]->m_BlockMeta) - ); - memset( - m_Sections[i]->m_BlockSkyLight, - 0xFF, - sizeof(m_Sections[i]->m_BlockSkyLight) - ); - } + // 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 * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); + memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes)); + memset(m_Sections[i]->m_BlockMeta, 0x00, sizeof(m_Sections[i]->m_BlockMeta)); + memset(m_Sections[i]->m_BlockSkyLight, 0xff, sizeof(m_Sections[i]->m_BlockSkyLight)); + } // for i - m_Sections[] } @@ -598,51 +529,29 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) return; } - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = CHUNK_SECTION_HEIGHT * 16 * 16 / 2; + // 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 * SegmentLength], - sizeof(NIBBLETYPE) * SegmentLength - ); + memcpy(&m_Sections[i]->m_BlockSkyLight, &a_Src[i * SegmentLength], sizeof(NIBBLETYPE) * SegmentLength); + continue; } - else + + // The section doesn't exist, find out if it is needed: + if (IsAllValue(a_Src + i * SegmentLength, SegmentLength, (NIBBLETYPE)0xff)) { - // j counts how many of leading zeros the buffer has - // if j == SegmentLength then the buffer is all zeros so there is no point - // creating the buffer. - size_t j = 0; - // do nothing whilst 0 - for (; (j < SegmentLength) && (a_Src[i * SegmentLength + j]) == 0xFF; j++); - if (j != SegmentLength) - { - m_Sections[i] = Allocate(); - memcpy( - &m_Sections[i]->m_BlockSkyLight, - &a_Src[i * SegmentLength], - sizeof(BLOCKTYPE) * SegmentLength - ); - memset( - m_Sections[i]->m_BlockTypes, - 0x00, - sizeof(m_Sections[i]->m_BlockTypes) - ); - memset( - m_Sections[i]->m_BlockMeta, - 0x00, - sizeof(m_Sections[i]->m_BlockMeta) - ); - memset( - m_Sections[i]->m_BlockLight, - 0x00, - sizeof(m_Sections[i]->m_BlockLight) - ); - } + // 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 * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); + memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes)); + memset(m_Sections[i]->m_BlockMeta, 0x00, sizeof(m_Sections[i]->m_BlockMeta)); + memset(m_Sections[i]->m_BlockLight, 0x00, sizeof(m_Sections[i]->m_BlockLight)); + } // for i - m_Sections[] } @@ -671,26 +580,10 @@ void cChunkData::Free(cChunkData::sChunkSection * 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_BlockMeta, - 0x00, - sizeof(a_Section->m_BlockMeta) - ); - memset( - a_Section->m_BlockLight, - 0x00, - sizeof(a_Section->m_BlockLight) - ); - memset( - a_Section->m_BlockSkyLight, - 0xFF, - sizeof(a_Section->m_BlockSkyLight) - ); + memset(a_Section->m_BlockTypes, 0x00, sizeof(a_Section->m_BlockTypes)); + memset(a_Section->m_BlockMeta, 0x00, sizeof(a_Section->m_BlockMeta)); + 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 index e6aaa99b8..341c15301 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -1,4 +1,12 @@ +// ChunkData.h + +// Declares the cChunkData class that represents the block's type, meta, blocklight and skylight storage for a chunk + + + + + #pragma once @@ -20,7 +28,7 @@ class cChunkData { public: - cChunkData(); + cChunkData(void); ~cChunkData(); #if __cplusplus < 201103L @@ -43,25 +51,48 @@ public: NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; + /** Creates a (deep) copy of self. */ cChunkData Copy(void) const; - // Copys data from this object into the buffer in the a_Dest param - // CopyBlocks also povides the optional parameters a_Idx and a_Length which specify an offset and length for - // copying part of the BlockTypes array. - void CopyBlocks (BLOCKTYPE * a_Dest, size_t a_Idx = 0, size_t a_Length = cChunkDef::NumBlocks) const; - void CopyMeta (NIBBLETYPE * a_Dest) 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; - void SetBlocks (const BLOCKTYPE * a_src); - void SetMeta (const NIBBLETYPE * a_src); - void SetBlockLight(const NIBBLETYPE * a_src); - void SetSkyLight (const NIBBLETYPE * a_src); + /** 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); private: - static const size_t CHUNK_SECTION_HEIGHT = 16; - static const size_t CHUNK_SECTION_COUNT = (256 / CHUNK_SECTION_HEIGHT); + static const size_t SectionHeight = 16; + static const size_t NumSections = (cChunkDef::Height / SectionHeight); + static const size_t SegmentLength = cChunkDef::Width * cChunkDef::Height * SectionHeight; + static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width; #if __cplusplus < 201103L // auto_ptr style interface for memory management @@ -69,13 +100,13 @@ private: #endif struct sChunkSection { - BLOCKTYPE m_BlockTypes [CHUNK_SECTION_HEIGHT * 16 * 16]; - NIBBLETYPE m_BlockMeta [CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; - NIBBLETYPE m_BlockLight [CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; - NIBBLETYPE m_BlockSkyLight[CHUNK_SECTION_HEIGHT * 16 * 16 / 2]; + BLOCKTYPE m_BlockTypes [SectionBlockCount]; + NIBBLETYPE m_BlockMeta [SectionBlockCount / 2]; + NIBBLETYPE m_BlockLight [SectionBlockCount / 2]; + NIBBLETYPE m_BlockSkyLight[SectionBlockCount / 2]; }; - sChunkSection * m_Sections[CHUNK_SECTION_COUNT]; + sChunkSection * m_Sections[NumSections]; /** Allocates a new section. Entry-point to custom allocators. */ static sChunkSection * Allocate(void); diff --git a/src/ChunkDataCallback.h b/src/ChunkDataCallback.h index e916d6486..0c8b1098f 100644 --- a/src/ChunkDataCallback.h +++ b/src/ChunkDataCallback.h @@ -1,11 +1,20 @@ +// 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. @@ -41,6 +50,10 @@ public: 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 : @@ -59,6 +72,9 @@ protected: }; + + + /** A simple implementation of the cChunkDataCallback interface that collects all block data into a single buffer */ class cChunkDataArrayCollector : @@ -73,15 +89,18 @@ protected: virtual void ChunkData(const cChunkData & a_ChunkBuffer) override { - a_ChunkBuffer.CopyBlocks(m_BlockData); - a_ChunkBuffer.CopyMeta(m_BlockData + cChunkDef::NumBlocks); + 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 a separate buffers -*/ + + + + +/** A simple implementation of the cChunkDataCallback interface that collects all block data into separate buffers */ class cChunkDataSeparateCollector : public cChunkDataCallback { @@ -96,10 +115,13 @@ protected: virtual void ChunkData(const cChunkData & a_ChunkBuffer) override { - a_ChunkBuffer.CopyBlocks(m_BlockTypes); - a_ChunkBuffer.CopyMeta(m_BlockMetas); - a_ChunkBuffer.CopyBlockLight(m_BlockLight); - a_ChunkBuffer.CopySkyLight(m_BlockSkyLight); + a_ChunkBuffer.CopyBlockTypes(m_BlockTypes); + a_ChunkBuffer.CopyMetas(m_BlockMetas); + a_ChunkBuffer.CopyBlockLight(m_BlockLight); + a_ChunkBuffer.CopySkyLight(m_BlockSkyLight); } } ; + + + diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 879252c34..dc19bf500 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -27,7 +27,7 @@ class cReader : { for (int z = 0; z < cChunkDef::Width; z++) { - a_ChunkBuffer.CopyBlocks(OutputRows + OutputIdx * 16, InputIdx * 16, 16); + a_ChunkBuffer.CopyBlockTypes(OutputRows + OutputIdx * 16, InputIdx * 16, 16); InputIdx++; OutputIdx += 3; } // for z From 80fe19c0e2e4433d8332dbe5a9c2fcba0be06f68 Mon Sep 17 00:00:00 2001 From: worktycho Date: Thu, 29 May 2014 17:41:07 +0100 Subject: [PATCH 166/312] Fixed overflow bug --- src/ChunkData.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index cc4793ec3..13be65fd7 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -333,25 +333,28 @@ cChunkData cChunkData::Copy(void) const void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const { - // TODO: This code seems wrong. It always copies into a_Dest[i * SegmentLength], even when a_Idx > 0 + size_t toskip = a_Idx; + for (size_t i = 0; i < NumSections; i++) { const size_t SegmentLength = SectionHeight * 16 * 16; - if (a_Idx > 0) + size_t startpos = 0; + if (toskip > 0) { - a_Idx = std::max(a_Idx - a_Length, (size_t) 0); + toskip = std::max(toskip - SegmentLength, (size_t) 0); + startpos = SegmentLength - toskip; } - if (a_Idx == 0) + if (toskip == 0) { size_t ToCopy = std::min(SegmentLength, a_Length); a_Length -= ToCopy; if (m_Sections[i] != NULL) { - memcpy(&a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockTypes, sizeof(BLOCKTYPE) * ToCopy); + memcpy(&a_Dest[(i * SegmentLength) - a_Idx], (&m_Sections[i]->m_BlockTypes) + startpos, sizeof(BLOCKTYPE) * (ToCopy - startpos)); } else { - memset(&a_Dest[i * SegmentLength], 0, sizeof(BLOCKTYPE) * ToCopy); + memset(&a_Dest[(i * SegmentLength) - a_Idx], 0, sizeof(BLOCKTYPE) * (ToCopy - startpos)); } } } From b4ba2209342d536e83b3461db00e9f9fd811120e Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 29 May 2014 19:21:56 +0200 Subject: [PATCH 167/312] Add SetOpen() and IsOpen() to BlockDoor.h and fix door redstone bug. --- src/Blocks/BlockDoor.h | 89 +++++++++++++++++-- .../IncrementalRedstoneSimulator.cpp | 14 ++- 2 files changed, 90 insertions(+), 13 deletions(-) diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 797fe484c..b5bfe4082 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)); @@ -128,21 +128,92 @@ public: } - /// 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) + /** Returns the metadata for the opposite door state (open vs closed) */ static NIBBLETYPE ChangeStateMetaData(NIBBLETYPE a_MetaData) { return a_MetaData ^ 4; } - /// Changes the door at the specified coords from open to close or vice versa + static bool IsOpen(cChunkInterface & a_ChunkInterface, int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) + { + BLOCKTYPE Block; + NIBBLETYPE Meta; + a_ChunkInterface.GetBlockTypeMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Block, Meta); + + if (!IsDoor(Block)) + { + return false; + } + + return ((Meta & 0x4) == 4); + } + + + static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open) + { + BLOCKTYPE Block; + NIBBLETYPE Meta; + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); + + if (!IsDoor(Block) || ((Meta & 0x4) == a_Open)) + { + return; + } + + // Change the door + if (a_Open) + { + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x4); + } + else + { + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0xFFFFFFFB); + } + + int OtherPartY = a_BlockY; + if (Meta & 0x8) + { + // Current block is top of the door + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY - 1, a_BlockZ, Block, Meta); + if (IsDoor(Block) && !(Meta & 0x8)) + { + OtherPartY--; + } + } + else + { + // Current block is bottom of the door + a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY + 1, a_BlockZ, Block, Meta); + if (IsDoor(Block) && (Meta & 0x8)) + { + OtherPartY++; + } + } + + // Change the other door part + if (a_BlockY != OtherPartY) + { + if (a_Open) + { + a_ChunkInterface.SetBlockMeta(a_BlockX, OtherPartY, a_BlockZ, Meta | 0x4); + } + else + { + a_ChunkInterface.SetBlockMeta(a_BlockX, OtherPartY, a_BlockZ, Meta & 0xFFFFFFFB); + } + } + } + + + /** 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) { NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_X, a_Y, a_Z); diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 074063add..d49142e4f 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -906,8 +906,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 +919,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); } } From c5763f3af700fe2df0be0ceb2fe9a580384c839e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 29 May 2014 19:42:39 +0200 Subject: [PATCH 168/312] Fixed test compilation. --- tests/ChunkData/ArraytoCoord.cpp | 12 ++++++------ tests/ChunkData/Copies.cpp | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/ChunkData/ArraytoCoord.cpp b/tests/ChunkData/ArraytoCoord.cpp index 37533de77..4942ababb 100644 --- a/tests/ChunkData/ArraytoCoord.cpp +++ b/tests/ChunkData/ArraytoCoord.cpp @@ -13,13 +13,13 @@ int main(int argc, char** argv) BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); SrcBlockBuffer[7 + (4 * 16) + (5 * 16 * 16)] = 0xCD; - buffer.SetBlocks(SrcBlockBuffer); + buffer.SetBlockTypes(SrcBlockBuffer); testassert(buffer.GetBlock(7,5,4) == 0xCD); NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 0xE; - buffer.SetMeta(SrcNibbleBuffer); + buffer.SetMetas(SrcNibbleBuffer); testassert(buffer.GetMeta(6, 2, 1) == 0xE); memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); @@ -40,13 +40,13 @@ int main(int argc, char** argv) BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); SrcBlockBuffer[7 + (4 * 16) + (24 * 16 * 16)] = 0xCD; - buffer.SetBlocks(SrcBlockBuffer); + buffer.SetBlockTypes(SrcBlockBuffer); testassert(buffer.GetBlock(7, 24, 4) == 0xCD); NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); SrcNibbleBuffer[(6 + (1 * 16) + (24 * 16 * 16)) / 2] = 0xE; - buffer.SetMeta(SrcNibbleBuffer); + buffer.SetMetas(SrcNibbleBuffer); testassert(buffer.GetMeta(6, 24, 1) == 0xE); memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); @@ -66,12 +66,12 @@ int main(int argc, char** argv) BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); - buffer.SetBlocks(SrcBlockBuffer); + buffer.SetBlockTypes(SrcBlockBuffer); testassert(buffer.GetBlock(7, 24, 4) == 0x00); NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256/2]; memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - buffer.SetMeta(SrcNibbleBuffer); + buffer.SetMetas(SrcNibbleBuffer); testassert(buffer.GetMeta(6, 24, 1) == 0x0); memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); diff --git a/tests/ChunkData/Copies.cpp b/tests/ChunkData/Copies.cpp index 78a458f5b..ef0329451 100644 --- a/tests/ChunkData/Copies.cpp +++ b/tests/ChunkData/Copies.cpp @@ -25,14 +25,14 @@ int main(int argc, char** argv) SrcBlockBuffer[i+3] = 0xEF; } - buffer.SetBlocks(SrcBlockBuffer); + buffer.SetBlockTypes(SrcBlockBuffer); BLOCKTYPE DstBlockBuffer[16 * 16 * 256]; - buffer.CopyBlocks(DstBlockBuffer); + buffer.CopyBlockTypes(DstBlockBuffer); testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) - 1) == 0); memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); - buffer.SetBlocks(SrcBlockBuffer); - buffer.CopyBlocks(DstBlockBuffer); + buffer.SetBlockTypes(SrcBlockBuffer); + buffer.CopyBlockTypes(DstBlockBuffer); testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) - 1) == 0); } @@ -48,14 +48,14 @@ int main(int argc, char** argv) SrcNibbleBuffer[i+3] = 0xBE; } - buffer.SetMeta(SrcNibbleBuffer); + buffer.SetMetas(SrcNibbleBuffer); NIBBLETYPE DstNibbleBuffer[16 * 16 * 256/ 2]; - buffer.CopyMeta(DstNibbleBuffer); + buffer.CopyMetas(DstNibbleBuffer); testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - buffer.SetMeta(SrcNibbleBuffer); - buffer.CopyMeta(DstNibbleBuffer); + buffer.SetMetas(SrcNibbleBuffer); + buffer.CopyMetas(DstNibbleBuffer); testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); @@ -114,13 +114,13 @@ int main(int argc, char** argv) BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); BLOCKTYPE DstBlockBuffer[16 * 16 * 256]; - buffer.CopyBlocks(DstBlockBuffer); + 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.CopyMeta(DstNibbleBuffer); + buffer.CopyMetas(DstNibbleBuffer); testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); From 0cfee5d141f63d0d9ee339e4fab3ad8ac15f884d Mon Sep 17 00:00:00 2001 From: worktycho Date: Thu, 29 May 2014 19:10:35 +0100 Subject: [PATCH 169/312] Fixed Wrong types in nibble sizeofs --- src/ChunkData.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 13be65fd7..46bd0b946 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -375,7 +375,7 @@ void cChunkData::CopyMetas(NIBBLETYPE * a_Dest) const } else { - memset(&a_Dest[i * SegmentLength], 0, sizeof(BLOCKTYPE) * SegmentLength); + memset(&a_Dest[i * SegmentLength], 0, sizeof(NIBBLETYPE) * SegmentLength); } } } @@ -395,7 +395,7 @@ void cChunkData::CopyBlockLight(NIBBLETYPE * a_Dest) const } else { - memset(&a_Dest[i * SegmentLength], 0, sizeof(BLOCKTYPE) * SegmentLength); + memset(&a_Dest[i * SegmentLength], 0, sizeof(NIBBLETYPE) * SegmentLength); } } } @@ -415,7 +415,7 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const } else { - memset(&a_Dest[i * SegmentLength], 0xff, sizeof(BLOCKTYPE) * SegmentLength); + memset(&a_Dest[i * SegmentLength], 0xff, sizeof(NIBBLETYPE) * SegmentLength); } } } From ab633c8bd65b333630053334cb1119f38788698d Mon Sep 17 00:00:00 2001 From: JoannisO Date: Thu, 29 May 2014 20:19:36 +0200 Subject: [PATCH 170/312] - Prefixed all args with "a_" - Added braces around the cases. --- src/BlockEntities/DispenserEntity.cpp | 14 +++++++++----- src/BlockEntities/DispenserEntity.h | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 341994be8..799d41a1e 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -196,15 +196,15 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) -void cDispenserEntity::SpawnProjectileFromDispenser(cChunk & a_Chunk, int & DispX, int & DispY, int & DispZ, cProjectileEntity::eKind kind) +void cDispenserEntity::SpawnProjectileFromDispenser(cChunk & a_Chunk, int & a_DispX, int & a_DispY, int & a_DispZ, cProjectileEntity::eKind a_kind) { Vector3d Angle = GetProjectileLookVector(a_Chunk); - cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(DispX, DispZ); + cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(a_DispX, a_DispZ); - double EntityX = 0.5 + (DispX + DispChunk->GetPosX() * cChunkDef::Width); - double EntityZ = 0.5 + (DispZ + DispChunk->GetPosZ() * cChunkDef::Width); + double EntityX = 0.5 + (a_DispX + DispChunk->GetPosX() * cChunkDef::Width); + double EntityZ = 0.5 + (a_DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - m_World->CreateProjectile((double) EntityX, (double) DispY + 0.5, (double) EntityZ, kind, NULL, NULL, &Angle); + m_World->CreateProjectile((double) EntityX, (double) a_DispY + 0.5, (double) EntityZ, a_kind, NULL, NULL, &Angle); } @@ -219,16 +219,20 @@ Vector3d cDispenserEntity::GetProjectileLookVector(cChunk & a_Chunk) switch (Meta) { case E_META_DROPSPENSER_FACING_YP: + { m.Init(Vector3d(), 0, 180, 0); Look = m.Transform(Vector3d(0, 1, 0)); return Look * 20; // UP + } case E_META_DROPSPENSER_FACING_YM: + { m.Init(Vector3d(), 0, -360, 0); Look = m.Transform(Vector3d(0, -1, 0)); return Look * 20;; // DOWN + } case E_META_DROPSPENSER_FACING_XM: Direction = 90; break; // WEST case E_META_DROPSPENSER_FACING_XP: Direction = 270; break; // EAST diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index 0b7cd6bea..76aaccd3c 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -30,7 +30,7 @@ private: bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType); // Spawns a projectile of the given kind in front of the dispenser - void SpawnProjectileFromDispenser(cChunk & a_Chunk, int & DispX, int & DispY, int & DispZ, cProjectileEntity::eKind kind); + void SpawnProjectileFromDispenser(cChunk & a_Chunk, int & a_DispX, int & a_DispY, int & a_DispZ, cProjectileEntity::eKind a_kind); // Returns how to aim the projectile Vector3d GetProjectileLookVector(cChunk & a_Chunk); From 59068b77b7215461b4aaf11c2db91c1657b7f91d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 29 May 2014 20:18:37 +0200 Subject: [PATCH 171/312] Fixed wrong block sizes for copying / setting. --- src/ChunkData.cpp | 75 ++++++++++++++++++-------------------- src/ChunkData.h | 3 +- tests/ChunkData/Copies.cpp | 32 ++++++++-------- 3 files changed, 52 insertions(+), 58 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 46bd0b946..2628b3410 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -208,7 +208,7 @@ NIBBLETYPE cChunkData::GetMeta(int a_RelX, int a_RelY, int a_RelZ) const if (m_Sections[Section] != NULL) { int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ); - return (m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + return (m_Sections[Section]->m_BlockMetas[Index / 2] >> ((Index & 1) * 4)) & 0x0f; } else { @@ -251,9 +251,9 @@ bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble ZeroSection(m_Sections[Section]); } int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * SectionHeight), a_RelZ); - NIBBLETYPE oldval = m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4) & 0xf; - m_Sections[Section]->m_BlockMeta[Index / 2] = static_cast( - (m_Sections[Section]->m_BlockMeta[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble + NIBBLETYPE oldval = m_Sections[Section]->m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0xf; + m_Sections[Section]->m_BlockMetas[Index / 2] = static_cast( + (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; @@ -333,28 +333,27 @@ cChunkData cChunkData::Copy(void) const void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const { - size_t toskip = a_Idx; + size_t ToSkip = a_Idx; for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = SectionHeight * 16 * 16; - size_t startpos = 0; - if (toskip > 0) + size_t StartPos = 0; + if (ToSkip > 0) { - toskip = std::max(toskip - SegmentLength, (size_t) 0); - startpos = SegmentLength - toskip; + ToSkip = std::max(ToSkip - SectionBlockCount, (size_t) 0); // TODO: Still can underflow + StartPos = SectionBlockCount - ToSkip; } - if (toskip == 0) + if (ToSkip == 0) { - size_t ToCopy = std::min(SegmentLength, a_Length); + size_t ToCopy = std::min(SectionBlockCount, a_Length); a_Length -= ToCopy; if (m_Sections[i] != NULL) { - memcpy(&a_Dest[(i * SegmentLength) - a_Idx], (&m_Sections[i]->m_BlockTypes) + startpos, sizeof(BLOCKTYPE) * (ToCopy - startpos)); + memcpy(&a_Dest[(i * SectionBlockCount) - a_Idx], (&m_Sections[i]->m_BlockTypes) + StartPos, sizeof(BLOCKTYPE) * (ToCopy - StartPos)); } else { - memset(&a_Dest[(i * SegmentLength) - a_Idx], 0, sizeof(BLOCKTYPE) * (ToCopy - startpos)); + memset(&a_Dest[(i * SectionBlockCount) - a_Idx], 0, sizeof(BLOCKTYPE) * (ToCopy - StartPos)); } } } @@ -368,14 +367,13 @@ void cChunkData::CopyMetas(NIBBLETYPE * a_Dest) const { for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = SectionHeight * 16 * 16 / 2; if (m_Sections[i] != NULL) { - memcpy(&a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockMeta, sizeof(NIBBLETYPE) * SegmentLength); + memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockMetas, sizeof(m_Sections[i]->m_BlockMetas)); } else { - memset(&a_Dest[i * SegmentLength], 0, sizeof(NIBBLETYPE) * SegmentLength); + memset(&a_Dest[i * SectionBlockCount / 2], 0, sizeof(m_Sections[i]->m_BlockMetas)); } } } @@ -388,14 +386,13 @@ void cChunkData::CopyBlockLight(NIBBLETYPE * a_Dest) const { for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = SectionHeight * 16 * 16 / 2; if (m_Sections[i] != NULL) { - memcpy(&a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockLight, sizeof(NIBBLETYPE) * SegmentLength); + memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockLight, sizeof(m_Sections[i]->m_BlockLight)); } else { - memset(&a_Dest[i * SegmentLength], 0, sizeof(NIBBLETYPE) * SegmentLength); + memset(&a_Dest[i * SectionBlockCount / 2], 0, sizeof(m_Sections[i]->m_BlockLight)); } } } @@ -408,14 +405,13 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const { for (size_t i = 0; i < NumSections; i++) { - const size_t SegmentLength = SectionHeight * 16 * 16 / 2; if (m_Sections[i] != NULL) { - memcpy(&a_Dest[i * SegmentLength], &m_Sections[i]->m_BlockSkyLight, sizeof(NIBBLETYPE) * SegmentLength); + memcpy(&a_Dest[i * SectionBlockCount / 2], &m_Sections[i]->m_BlockSkyLight, sizeof(m_Sections[i]->m_BlockSkyLight)); } else { - memset(&a_Dest[i * SegmentLength], 0xff, sizeof(NIBBLETYPE) * SegmentLength); + memset(&a_Dest[i * SectionBlockCount / 2], 0xff, sizeof(m_Sections[i]->m_BlockSkyLight)); } } } @@ -428,18 +424,17 @@ void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) { ASSERT(a_Src != NULL); - static const size_t SegmentLength = SectionHeight * 16 * 16; 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 * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); + 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 * SegmentLength, SegmentLength, (const BLOCKTYPE)0)) + if (IsAllValue(a_Src + i * SectionBlockCount, SectionBlockCount, (const BLOCKTYPE)0)) { // No need for the section, the data is all-air continue; @@ -447,8 +442,8 @@ void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(&m_Sections[i]->m_BlockTypes, &a_Src[i * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); - memset(m_Sections[i]->m_BlockMeta, 0x00, sizeof(m_Sections[i]->m_BlockMeta)); + 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[] @@ -466,12 +461,12 @@ void cChunkData::SetMetas(const NIBBLETYPE * a_Src) // If the section is already allocated, copy the data into it: if (m_Sections[i] != NULL) { - memcpy(&m_Sections[i]->m_BlockMeta, &a_Src[i * SegmentLength], sizeof(NIBBLETYPE) * SegmentLength); + memcpy(&m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockMetas)); continue; } // The section doesn't exist, find out if it is needed: - if (IsAllValue(a_Src + i * SegmentLength, SegmentLength, (NIBBLETYPE)0)) + if (IsAllValue(a_Src + i * SectionBlockCount, SectionBlockCount, (NIBBLETYPE)0)) { // No need for the section, the data is all zeroes continue; @@ -479,7 +474,7 @@ void cChunkData::SetMetas(const NIBBLETYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(&m_Sections[i]->m_BlockMeta, &a_Src[i * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); + memcpy(&m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount], 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)); @@ -502,12 +497,12 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) // 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 * SegmentLength], sizeof(NIBBLETYPE) * SegmentLength); + memcpy(&m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount], sizeof(NIBBLETYPE) * SectionBlockCount); continue; } // The section doesn't exist, find out if it is needed: - if (IsAllValue(a_Src + i * SegmentLength, SegmentLength, (NIBBLETYPE)0)) + if (IsAllValue(a_Src + i * SectionBlockCount, SectionBlockCount, (NIBBLETYPE)0)) { // No need for the section, the data is all zeroes continue; @@ -515,9 +510,9 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(&m_Sections[i]->m_BlockLight, &a_Src[i * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); + memcpy(&m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount], sizeof(BLOCKTYPE) * SectionBlockCount); memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes)); - memset(m_Sections[i]->m_BlockMeta, 0x00, sizeof(m_Sections[i]->m_BlockMeta)); + 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[] } @@ -537,12 +532,12 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) // 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 * SegmentLength], sizeof(NIBBLETYPE) * SegmentLength); + memcpy(&m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount], sizeof(NIBBLETYPE) * SectionBlockCount); continue; } // The section doesn't exist, find out if it is needed: - if (IsAllValue(a_Src + i * SegmentLength, SegmentLength, (NIBBLETYPE)0xff)) + if (IsAllValue(a_Src + i * SectionBlockCount, SectionBlockCount, (NIBBLETYPE)0xff)) { // No need for the section, the data is all zeroes continue; @@ -550,9 +545,9 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(&m_Sections[i]->m_BlockSkyLight, &a_Src[i * SegmentLength], sizeof(BLOCKTYPE) * SegmentLength); + memcpy(&m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount], sizeof(BLOCKTYPE) * SectionBlockCount); memset(m_Sections[i]->m_BlockTypes, 0x00, sizeof(m_Sections[i]->m_BlockTypes)); - memset(m_Sections[i]->m_BlockMeta, 0x00, sizeof(m_Sections[i]->m_BlockMeta)); + 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[] } @@ -584,7 +579,7 @@ void cChunkData::Free(cChunkData::sChunkSection * 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_BlockMeta, 0x00, sizeof(a_Section->m_BlockMeta)); + 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 index 341c15301..fef31b5ad 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -91,7 +91,6 @@ private: static const size_t SectionHeight = 16; static const size_t NumSections = (cChunkDef::Height / SectionHeight); - static const size_t SegmentLength = cChunkDef::Width * cChunkDef::Height * SectionHeight; static const size_t SectionBlockCount = SectionHeight * cChunkDef::Width * cChunkDef::Width; #if __cplusplus < 201103L @@ -101,7 +100,7 @@ private: struct sChunkSection { BLOCKTYPE m_BlockTypes [SectionBlockCount]; - NIBBLETYPE m_BlockMeta [SectionBlockCount / 2]; + NIBBLETYPE m_BlockMetas [SectionBlockCount / 2]; NIBBLETYPE m_BlockLight [SectionBlockCount / 2]; NIBBLETYPE m_BlockSkyLight[SectionBlockCount / 2]; }; diff --git a/tests/ChunkData/Copies.cpp b/tests/ChunkData/Copies.cpp index ef0329451..788d2c558 100644 --- a/tests/ChunkData/Copies.cpp +++ b/tests/ChunkData/Copies.cpp @@ -19,10 +19,10 @@ int main(int argc, char** argv) 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; + SrcBlockBuffer[i + 0] = 0xde; + SrcBlockBuffer[i + 1] = 0xad; + SrcBlockBuffer[i + 2] = 0xbe; + SrcBlockBuffer[i + 3] = 0xef; } buffer.SetBlockTypes(SrcBlockBuffer); @@ -42,10 +42,10 @@ int main(int argc, char** argv) NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) { - SrcNibbleBuffer[i+0] = 0xEF; - SrcNibbleBuffer[i+1] = 0xDE; - SrcNibbleBuffer[i+2] = 0xAD; - SrcNibbleBuffer[i+3] = 0xBE; + SrcNibbleBuffer[i + 0] = 0xde; + SrcNibbleBuffer[i + 1] = 0xad; + SrcNibbleBuffer[i + 2] = 0xbe; + SrcNibbleBuffer[i + 3] = 0xef; } buffer.SetMetas(SrcNibbleBuffer); @@ -66,10 +66,10 @@ int main(int argc, char** argv) 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; + SrcNibbleBuffer[i + 0] = 0xde; + SrcNibbleBuffer[i + 1] = 0xad; + SrcNibbleBuffer[i + 2] = 0xbe; + SrcNibbleBuffer[i + 3] = 0xef; } buffer.SetBlockLight(SrcNibbleBuffer); @@ -90,10 +90,10 @@ int main(int argc, char** argv) NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; for (int i = 0; i < 16 * 16 * 256 / 2; i += 4) { - SrcNibbleBuffer[i+0] = 0xAD; - SrcNibbleBuffer[i+1] = 0xBE; - SrcNibbleBuffer[i+2] = 0xEF; - SrcNibbleBuffer[i+3] = 0xDE; + SrcNibbleBuffer[i + 0] = 0xde; + SrcNibbleBuffer[i + 1] = 0xad; + SrcNibbleBuffer[i + 2] = 0xbe; + SrcNibbleBuffer[i + 3] = 0xef; } buffer.SetSkyLight(SrcNibbleBuffer); From b50181e3614286b9624cf3b8f296d7b25509a55d Mon Sep 17 00:00:00 2001 From: worktycho Date: Thu, 29 May 2014 19:29:06 +0100 Subject: [PATCH 172/312] fix underflow Wish c++ could specify saturating unsigned underflow. --- src/ChunkData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 2628b3410..72187f393 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -340,7 +340,7 @@ void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Lengt size_t StartPos = 0; if (ToSkip > 0) { - ToSkip = std::max(ToSkip - SectionBlockCount, (size_t) 0); // TODO: Still can underflow + ToSkip = std::max((ssize_t)ToSkip - (ssize_t)SectionBlockCount, (size_t) 0); StartPos = SectionBlockCount - ToSkip; } if (ToSkip == 0) From 901e3ec4940f2a11f7866194f02732c813ce71b9 Mon Sep 17 00:00:00 2001 From: worktycho Date: Thu, 29 May 2014 19:35:47 +0100 Subject: [PATCH 173/312] Derp --- src/ChunkData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 72187f393..382e7a5a8 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -340,7 +340,7 @@ void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Lengt size_t StartPos = 0; if (ToSkip > 0) { - ToSkip = std::max((ssize_t)ToSkip - (ssize_t)SectionBlockCount, (size_t) 0); + ToSkip = std::max((ssize_t)ToSkip - (ssize_t)SectionBlockCount, (ssize_t) 0); StartPos = SectionBlockCount - ToSkip; } if (ToSkip == 0) From be10f07db02565fad77937bc6e9ccc6580f19158 Mon Sep 17 00:00:00 2001 From: worktycho Date: Thu, 29 May 2014 19:44:36 +0100 Subject: [PATCH 174/312] Fix bug when a_Idx is not a multiple of SectionBLockCount --- src/ChunkData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 382e7a5a8..be96be051 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -343,7 +343,7 @@ void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Lengt ToSkip = std::max((ssize_t)ToSkip - (ssize_t)SectionBlockCount, (ssize_t) 0); StartPos = SectionBlockCount - ToSkip; } - if (ToSkip == 0) + if (ToSkip < SectionBlockCount) { size_t ToCopy = std::min(SectionBlockCount, a_Length); a_Length -= ToCopy; From 8c4dd5dcfd91f8223e78ff7fd24f8e4e73d1f509 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 29 May 2014 21:41:44 +0200 Subject: [PATCH 175/312] Attempt at fixing an unresolved symbol in gcc / clang. --- src/ChunkData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index be96be051..74f5d78ba 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -345,7 +345,7 @@ void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Lengt } if (ToSkip < SectionBlockCount) { - size_t ToCopy = std::min(SectionBlockCount, a_Length); + size_t ToCopy = std::min(+SectionBlockCount, a_Length); a_Length -= ToCopy; if (m_Sections[i] != NULL) { From 0e2138736cd969a0dc931bbef31262da906cb832 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 30 May 2014 09:17:17 +0200 Subject: [PATCH 176/312] Fixed wrong copy sizes in cChunkData. --- src/ChunkData.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 74f5d78ba..5c11212ea 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -333,14 +333,14 @@ cChunkData cChunkData::Copy(void) const void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const { - size_t ToSkip = a_Idx; + int ToSkip = a_Idx; for (size_t i = 0; i < NumSections; i++) { size_t StartPos = 0; if (ToSkip > 0) { - ToSkip = std::max((ssize_t)ToSkip - (ssize_t)SectionBlockCount, (ssize_t) 0); + ToSkip = std::max(ToSkip - (int)SectionBlockCount, 0); StartPos = SectionBlockCount - ToSkip; } if (ToSkip < SectionBlockCount) @@ -429,7 +429,7 @@ void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) // 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)); + memcpy(m_Sections[i]->m_BlockTypes, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockTypes)); continue; } @@ -442,7 +442,7 @@ void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) // 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)); + 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)); @@ -461,7 +461,7 @@ void cChunkData::SetMetas(const NIBBLETYPE * a_Src) // 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], sizeof(m_Sections[i]->m_BlockMetas)); + memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockMetas)); continue; } @@ -474,7 +474,7 @@ void cChunkData::SetMetas(const NIBBLETYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(&m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockMetas)); + memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount], 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)); @@ -497,7 +497,7 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) // 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], sizeof(NIBBLETYPE) * SectionBlockCount); + memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockLight)); continue; } @@ -510,7 +510,7 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(&m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount], sizeof(BLOCKTYPE) * SectionBlockCount); + memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount], 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)); @@ -532,7 +532,7 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) // 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], sizeof(NIBBLETYPE) * SectionBlockCount); + memcpy(m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockSkyLight)); continue; } @@ -545,7 +545,7 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(&m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount], sizeof(BLOCKTYPE) * SectionBlockCount); + memcpy(m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount], 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)); From 0b49529e4273a96e7f582ef4c321eaf8d65c629f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 30 May 2014 09:17:50 +0200 Subject: [PATCH 177/312] Fixed test return values. --- tests/ChunkData/ArraytoCoord.cpp | 65 +++++++++++++++++--------------- tests/ChunkData/Copies.cpp | 14 +++---- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/tests/ChunkData/ArraytoCoord.cpp b/tests/ChunkData/ArraytoCoord.cpp index 4942ababb..0daf38f7b 100644 --- a/tests/ChunkData/ArraytoCoord.cpp +++ b/tests/ChunkData/ArraytoCoord.cpp @@ -11,26 +11,26 @@ int main(int argc, char** argv) cChunkData buffer; BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; - memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); - SrcBlockBuffer[7 + (4 * 16) + (5 * 16 * 16)] = 0xCD; + memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer)); + SrcBlockBuffer[7 + (4 * 16) + (5 * 16 * 16)] = 0xcd; buffer.SetBlockTypes(SrcBlockBuffer); - testassert(buffer.GetBlock(7,5,4) == 0xCD); + testassert(buffer.GetBlock(7, 5, 4) == 0xcd); NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); - SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 0xE; + memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer)); + SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 0xe; buffer.SetMetas(SrcNibbleBuffer); - testassert(buffer.GetMeta(6, 2, 1) == 0xE); + testassert(buffer.GetMeta(6, 2, 1) == 0xe); - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); - SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 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); + testassert(buffer.GetBlockLight(6, 2, 1) == 0xe); - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); - SrcNibbleBuffer[(6 + (1 * 16) + (2 * 16 * 16)) / 2] = 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); + testassert(buffer.GetSkyLight(6, 2, 1) == 0xe); } { @@ -38,26 +38,26 @@ int main(int argc, char** argv) cChunkData buffer; BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; - memset(SrcBlockBuffer, 0x00, 16 * 16 * 256); - SrcBlockBuffer[7 + (4 * 16) + (24 * 16 * 16)] = 0xCD; + memset(SrcBlockBuffer, 0x00, sizeof(SrcBlockBuffer)); + SrcBlockBuffer[7 + (4 * 16) + (24 * 16 * 16)] = 0xcd; buffer.SetBlockTypes(SrcBlockBuffer); - testassert(buffer.GetBlock(7, 24, 4) == 0xCD); + testassert(buffer.GetBlock(7, 24, 4) == 0xcd); NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 / 2); - SrcNibbleBuffer[(6 + (1 * 16) + (24 * 16 * 16)) / 2] = 0xE; + memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer)); + SrcNibbleBuffer[(6 + (1 * 16) + (24 * 16 * 16)) / 2] = 0xe; buffer.SetMetas(SrcNibbleBuffer); - testassert(buffer.GetMeta(6, 24, 1) == 0xE); + testassert(buffer.GetMeta(6, 24, 1) == 0xe); - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); - SrcNibbleBuffer[(6+1*16+24*16*16)/2] = 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); + testassert(buffer.GetBlockLight(6, 24, 1) == 0xe); - memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 / 2); - SrcNibbleBuffer[(6 + (1 * 16) + (24 * 16 * 16))/2] = 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); + testassert(buffer.GetSkyLight(6, 24, 1) == 0xe); } { @@ -65,22 +65,25 @@ int main(int argc, char** argv) cChunkData buffer; BLOCKTYPE SrcBlockBuffer[16 * 16 * 256]; - memset(SrcBlockBuffer, 0x00, 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, 16 * 16 * 256 /2); + NIBBLETYPE SrcNibbleBuffer[16 * 16 * 256 / 2]; + memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer)); buffer.SetMetas(SrcNibbleBuffer); testassert(buffer.GetMeta(6, 24, 1) == 0x0); - memset(SrcNibbleBuffer, 0x00, 16 * 16 * 256 /2); + memset(SrcNibbleBuffer, 0x00, sizeof(SrcNibbleBuffer)); buffer.SetBlockLight(SrcNibbleBuffer); - testassert(buffer.GetBlockLight(6,24,1) == 0x0); + testassert(buffer.GetBlockLight(6, 24, 1) == 0x0); - memset(SrcNibbleBuffer, 0xFF, 16 * 16 * 256 /2); + memset(SrcNibbleBuffer, 0xff, sizeof(SrcNibbleBuffer)); buffer.SetSkyLight(SrcNibbleBuffer); - testassert(buffer.GetSkyLight(6, 24, 1) == 0xF); + testassert(buffer.GetSkyLight(6, 24, 1) == 0xf); } + + // All tests passed: + return 0; } diff --git a/tests/ChunkData/Copies.cpp b/tests/ChunkData/Copies.cpp index 788d2c558..312441eee 100644 --- a/tests/ChunkData/Copies.cpp +++ b/tests/ChunkData/Copies.cpp @@ -34,8 +34,8 @@ int main(int argc, char** argv) buffer.SetBlockTypes(SrcBlockBuffer); buffer.CopyBlockTypes(DstBlockBuffer); testassert(memcmp(SrcBlockBuffer, DstBlockBuffer, (16 * 16 * 256) - 1) == 0); - } + { cChunkData buffer; @@ -57,9 +57,8 @@ int main(int argc, char** argv) buffer.SetMetas(SrcNibbleBuffer); buffer.CopyMetas(DstNibbleBuffer); testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); - - } + { cChunkData buffer; @@ -81,9 +80,8 @@ int main(int argc, char** argv) buffer.SetBlockLight(SrcNibbleBuffer); buffer.CopyBlockLight(DstNibbleBuffer); testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 /2) - 1) == 0); - - } + { cChunkData buffer; @@ -101,13 +99,12 @@ int main(int argc, char** argv) 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; @@ -131,4 +128,7 @@ int main(int argc, char** argv) buffer.CopySkyLight(DstNibbleBuffer); testassert(memcmp(SrcNibbleBuffer, DstNibbleBuffer, (16 * 16 * 256 / 2) - 1) == 0); } + + // All tests successful: + return 0; } From 5368c5dd79bce465d32517eec62701abc9b380d9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 30 May 2014 09:49:57 +0200 Subject: [PATCH 178/312] Fixed sign comparison. --- src/ChunkData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 5c11212ea..6ccb28fe4 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -343,7 +343,7 @@ void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Lengt ToSkip = std::max(ToSkip - (int)SectionBlockCount, 0); StartPos = SectionBlockCount - ToSkip; } - if (ToSkip < SectionBlockCount) + if (ToSkip < (int)SectionBlockCount) { size_t ToCopy = std::min(+SectionBlockCount, a_Length); a_Length -= ToCopy; From 0b60caac4ae8e7762cc530a0a7b6a7abe8c33262 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 30 May 2014 10:56:12 +0200 Subject: [PATCH 179/312] Test failures are reported verbosely and into the debug console on Win. --- src/Globals.h | 20 ++++++++++++++++++-- tests/ChunkData/CMakeLists.txt | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Globals.h b/src/Globals.h index 85cfd2f18..7b7a34541 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -271,9 +271,25 @@ void inline LOGERROR(const char* a_Format, ...) { }; + #ifdef _WIN32 + #define REPORT_ERROR(FMT, ...) \ + { \ + AString msg = Printf(FMT, __VA_ARGS__); \ + puts(msg.c_str()); \ + fflush(stdout); \ + OutputDebugStringA(msg.c_str()); \ + } + #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)) { exit(1); } } while (0) - #define CheckAsserts(x) do { try {x} catch (cAssertFailure) { break; } exit(1); } 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 #ifdef _DEBUG diff --git a/tests/ChunkData/CMakeLists.txt b/tests/ChunkData/CMakeLists.txt index a2bd9fd22..fd508cc6e 100644 --- a/tests/ChunkData/CMakeLists.txt +++ b/tests/ChunkData/CMakeLists.txt @@ -5,7 +5,7 @@ enable_testing() include_directories(${CMAKE_SOURCE_DIR}/src/) add_definitions(-DTEST_GLOBALS=1) -add_library(ChunkBuffer ${CMAKE_SOURCE_DIR}/src/ChunkData.cpp) +add_library(ChunkBuffer ${CMAKE_SOURCE_DIR}/src/ChunkData.cpp ${CMAKE_SOURCE_DIR}/src/StringUtils.cpp) add_executable(creatable-exe creatable.cpp) From 730e36844e152794cf85c4d1e9b7a84fd8be86ee Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 30 May 2014 11:01:13 +0200 Subject: [PATCH 180/312] Test failures break into MSVC debugger. --- src/Globals.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Globals.h b/src/Globals.h index 7b7a34541..c5768facf 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -272,12 +272,18 @@ void inline LOGERROR(const char* a_Format, ...) }; #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, ...) \ From e136f6e0f5b41ee7c9d784009ef40c9ac2e2e6fe Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 30 May 2014 11:35:29 +0200 Subject: [PATCH 181/312] Fixed cChunkData nibble copying. --- src/ChunkData.cpp | 18 +++++++++--------- tests/ChunkData/Coordinates.cpp | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 6ccb28fe4..6178dbc0d 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -461,12 +461,12 @@ void cChunkData::SetMetas(const NIBBLETYPE * a_Src) // 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], sizeof(m_Sections[i]->m_BlockMetas)); + 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, SectionBlockCount, (NIBBLETYPE)0)) + if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, (NIBBLETYPE)0)) { // No need for the section, the data is all zeroes continue; @@ -474,7 +474,7 @@ void cChunkData::SetMetas(const NIBBLETYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockMetas)); + 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)); @@ -497,12 +497,12 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) // 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], sizeof(m_Sections[i]->m_BlockLight)); + 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, SectionBlockCount, (NIBBLETYPE)0)) + if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, (NIBBLETYPE)0)) { // No need for the section, the data is all zeroes continue; @@ -510,7 +510,7 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockLight)); + 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)); @@ -532,12 +532,12 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) // 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], sizeof(m_Sections[i]->m_BlockSkyLight)); + 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, SectionBlockCount, (NIBBLETYPE)0xff)) + if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, (NIBBLETYPE)0xff)) { // No need for the section, the data is all zeroes continue; @@ -545,7 +545,7 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); - memcpy(m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockSkyLight)); + 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)); diff --git a/tests/ChunkData/Coordinates.cpp b/tests/ChunkData/Coordinates.cpp index 938c66dcc..48d731c7e 100644 --- a/tests/ChunkData/Coordinates.cpp +++ b/tests/ChunkData/Coordinates.cpp @@ -109,14 +109,14 @@ int main(int argc, char** argv) // Zero's buffer.SetBlock(0, 0, 0, 0x0); - buffer.SetBlock(0, 0, 1, 0xAB); + buffer.SetBlock(0, 0, 1, 0xab); testassert(buffer.GetBlock(0, 0, 0) == 0x0); - testassert(buffer.GetBlock(0, 0, 1) == 0xAB); + testassert(buffer.GetBlock(0, 0, 1) == 0xab); buffer.SetMeta(0, 16, 0, 0x0); - buffer.SetMeta(0, 16, 1, 0xC); + buffer.SetMeta(0, 16, 1, 0xc); testassert(buffer.GetMeta(0, 16, 0) == 0x0); - testassert(buffer.GetMeta(0, 16, 1) == 0xC); + testassert(buffer.GetMeta(0, 16, 1) == 0xc); } From d854d3af1c724304997488d2b61518c85acb076a Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 30 May 2014 14:43:33 +0100 Subject: [PATCH 182/312] removed unneded addressof --- src/ChunkData.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 6178dbc0d..258853ea0 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -55,6 +55,7 @@ cChunkData::~cChunkData() for (size_t i = 0; i < NumSections; i++) { Free(m_Sections[i]); + m_Sections[i] = NULL; } } @@ -93,6 +94,7 @@ cChunkData::~cChunkData() for (size_t i = 0; i < NumSections; i++) { Free(m_Sections[i]); + m_Sections[i] = NULL; } } @@ -101,6 +103,7 @@ cChunkData::~cChunkData() for (size_t i = 0; i < NumSections; i++) { m_Sections[i] = a_Other.m_Sections[i]; + a_Other.m_Sections[i] = NULL; } a_Other.m_IsOwner = false; return *this; @@ -333,27 +336,28 @@ cChunkData cChunkData::Copy(void) const void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const { - int ToSkip = a_Idx; + size_t ToSkip = a_Idx; for (size_t i = 0; i < NumSections; i++) { size_t StartPos = 0; if (ToSkip > 0) { - ToSkip = std::max(ToSkip - (int)SectionBlockCount, 0); - StartPos = SectionBlockCount - ToSkip; + StartPos = std::min(ToSkip, +SectionBlockCount); + ToSkip -= StartPos; } - if (ToSkip < (int)SectionBlockCount) + if (StartPos < SectionBlockCount) { - size_t ToCopy = std::min(+SectionBlockCount, a_Length); + size_t ToCopy = std::min(+SectionBlockCount - StartPos, a_Length); a_Length -= ToCopy; if (m_Sections[i] != NULL) { - memcpy(&a_Dest[(i * SectionBlockCount) - a_Idx], (&m_Sections[i]->m_BlockTypes) + StartPos, sizeof(BLOCKTYPE) * (ToCopy - StartPos)); + 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 - StartPos)); + memset(&a_Dest[(i * SectionBlockCount) - a_Idx], 0, sizeof(BLOCKTYPE) * ToCopy); } } } From f26ddac61944ccae3223be5c4403171e04e306b9 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 30 May 2014 14:50:30 +0100 Subject: [PATCH 183/312] removed NULL assignment to const value --- src/ChunkData.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 258853ea0..142c141c4 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -103,7 +103,6 @@ cChunkData::~cChunkData() for (size_t i = 0; i < NumSections; i++) { m_Sections[i] = a_Other.m_Sections[i]; - a_Other.m_Sections[i] = NULL; } a_Other.m_IsOwner = false; return *this; From 76c07b1ec72033d05a4dd54360451f6492c2a31e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 30 May 2014 17:44:24 +0200 Subject: [PATCH 184/312] Added a cChunkData::CopyBlockTypes() unit test. --- tests/ChunkData/CMakeLists.txt | 3 ++ tests/ChunkData/CopyBlocks.cpp | 65 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 tests/ChunkData/CopyBlocks.cpp diff --git a/tests/ChunkData/CMakeLists.txt b/tests/ChunkData/CMakeLists.txt index fd508cc6e..381e11cc2 100644 --- a/tests/ChunkData/CMakeLists.txt +++ b/tests/ChunkData/CMakeLists.txt @@ -24,3 +24,6 @@ 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/CopyBlocks.cpp b/tests/ChunkData/CopyBlocks.cpp new file mode 100644 index 000000000..d132411db --- /dev/null +++ b/tests/ChunkData/CopyBlocks.cpp @@ -0,0 +1,65 @@ + +// 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: + cChunkData Data; + 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)); + for (size_t idx = 0; idx < 5000; idx++) + { + for (size_t len = 1; len < 1000; len += 15) + { + printf("Testing copying %u blocks from index %u\n", (unsigned)len, (unsigned)idx); + + 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 + idx; 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); + } + } + } // for idx + return 0; +} + + + + + From cbb9e152577e3db07832b96583f0ab0618d0d983 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 30 May 2014 17:13:36 +0100 Subject: [PATCH 185/312] Fix bugs in test --- tests/ChunkData/CopyBlocks.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/ChunkData/CopyBlocks.cpp b/tests/ChunkData/CopyBlocks.cpp index d132411db..b31ce3c63 100644 --- a/tests/ChunkData/CopyBlocks.cpp +++ b/tests/ChunkData/CopyBlocks.cpp @@ -30,12 +30,14 @@ int main(int argc, char ** argv) BLOCKTYPE TestBuffer[5 * cChunkDef::NumBlocks]; size_t WritePosIdx = 2 * cChunkDef::NumBlocks; BLOCKTYPE * WritePosition = &TestBuffer[WritePosIdx]; - memset(TestBuffer, 0x03, sizeof(TestBuffer)); for (size_t idx = 0; idx < 5000; idx++) { for (size_t len = 1; len < 1000; len += 15) { - printf("Testing copying %u blocks from index %u\n", (unsigned)len, (unsigned)idx); + //printf("Testing copying %u blocks from index %u\n", (unsigned)len, (unsigned)idx); + + //initalize buffer + memset(TestBuffer, 0x03, sizeof(TestBuffer)); Data.CopyBlockTypes(WritePosition, idx, len); @@ -45,7 +47,7 @@ int main(int argc, char ** argv) assert_test(WritePosition[i] == 0x01); } // Verify the space before the copied data hasn't been changed: - for (size_t i = 0; i < WritePosIdx + idx; i++) + for (size_t i = 0; i < WritePosIdx; i++) { assert_test(TestBuffer[i] == 0x03); } From f2470ff7c11fc8226b20a5d53f5a4e8ee0e8454e Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 30 May 2014 18:32:15 +0200 Subject: [PATCH 186/312] Reduced the number of cChunkData::CopyBlockTypes() tests, added progress. --- tests/ChunkData/CopyBlocks.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/ChunkData/CopyBlocks.cpp b/tests/ChunkData/CopyBlocks.cpp index b31ce3c63..be8cab234 100644 --- a/tests/ChunkData/CopyBlocks.cpp +++ b/tests/ChunkData/CopyBlocks.cpp @@ -30,15 +30,18 @@ int main(int argc, char ** argv) BLOCKTYPE TestBuffer[5 * cChunkDef::NumBlocks]; size_t WritePosIdx = 2 * cChunkDef::NumBlocks; BLOCKTYPE * WritePosition = &TestBuffer[WritePosIdx]; - for (size_t idx = 0; idx < 5000; idx++) + memset(TestBuffer, 0x03, sizeof(TestBuffer)); + size_t LastReportedStep = 1; + for (size_t idx = 0; idx < 5000; idx += 7) { - for (size_t len = 1; len < 1000; len += 15) + if (idx / 500 != LastReportedStep) { - //printf("Testing copying %u blocks from index %u\n", (unsigned)len, (unsigned)idx); - - //initalize buffer - memset(TestBuffer, 0x03, sizeof(TestBuffer)); + 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: @@ -56,7 +59,13 @@ int main(int argc, char ** argv) { 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; } From d8e16f8c1fa771f77ef7505b45b9114b1f75aa61 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 30 May 2014 22:22:42 +0200 Subject: [PATCH 187/312] Better SetOpen() and IsOpen() function from the doors. --- src/Blocks/BlockDoor.cpp | 2 +- src/Blocks/BlockDoor.h | 106 +++++++++++---------------------------- 2 files changed, 29 insertions(+), 79 deletions(-) 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 b5bfe4082..c1e4de9d4 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -135,113 +135,63 @@ public: } - /** 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 = GetMetaFromRightDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + return ((Meta & 0x4) != 0); } - static bool IsOpen(cChunkInterface & a_ChunkInterface, int a_RelBlockX, int a_RelBlockY, int a_RelBlockZ) + static NIBBLETYPE GetMetaFromRightDoor(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { - BLOCKTYPE Block; - NIBBLETYPE Meta; - a_ChunkInterface.GetBlockTypeMeta(a_RelBlockX, a_RelBlockY, a_RelBlockZ, Block, Meta); + NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (!IsDoor(Block)) + if ((Meta & 0x8) != 0) { - return false; + NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); + return (DownMeta & 0x7) | 0x8 | (((Meta & 0x1) != 0) ? 16 : 0); + } + else + { + NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ); + return (Meta & 0x7) | (((UpMeta & 0x1) != 0) ? 16 : 0); } - - return ((Meta & 0x4) == 4); } static void SetOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Open) { - BLOCKTYPE Block; - NIBBLETYPE Meta; - a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); + BLOCKTYPE Block = a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE Meta = GetMetaFromRightDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - if (!IsDoor(Block) || ((Meta & 0x4) == a_Open)) + if (!IsDoor(Block)) + { + return; + } + + bool Opened = (Meta & 0x4) != 0; + if (Opened == a_Open) { return; } // Change the door - if (a_Open) + NIBBLETYPE NewMeta = (Meta & 0x7) ^ 0x4; + if ((Meta & 0x8) == 0) { - a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x4); + a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, NewMeta); } else { - a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0xFFFFFFFB); - } - - int OtherPartY = a_BlockY; - if (Meta & 0x8) - { - // Current block is top of the door - a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY - 1, a_BlockZ, Block, Meta); - if (IsDoor(Block) && !(Meta & 0x8)) - { - OtherPartY--; - } - } - else - { - // Current block is bottom of the door - a_ChunkInterface.GetBlockTypeMeta(a_BlockX, a_BlockY + 1, a_BlockZ, Block, Meta); - if (IsDoor(Block) && (Meta & 0x8)) - { - OtherPartY++; - } - } - - // Change the other door part - if (a_BlockY != OtherPartY) - { - if (a_Open) - { - a_ChunkInterface.SetBlockMeta(a_BlockX, OtherPartY, a_BlockZ, Meta | 0x4); - } - else - { - a_ChunkInterface.SetBlockMeta(a_BlockX, OtherPartY, a_BlockZ, Meta & 0xFFFFFFFB); - } + 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_X, int a_Y, int a_Z) + static void ChangeDoor(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)); - - if (OldMetaData & 8) - { - // Current block is top of the door - BLOCKTYPE BottomBlock = a_ChunkInterface.GetBlock(a_X, a_Y - 1, a_Z); - NIBBLETYPE BottomMeta = a_ChunkInterface.GetBlockMeta(a_X, a_Y - 1, a_Z); - - if (IsDoor(BottomBlock) && !(BottomMeta & 8)) - { - a_ChunkInterface.SetBlockMeta(a_X, a_Y - 1, a_Z, ChangeStateMetaData(BottomMeta)); - } - } - 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); - - if (IsDoor(TopBlock) && (TopMeta & 8)) - { - a_ChunkInterface.SetBlockMeta(a_X, a_Y + 1, a_Z, ChangeStateMetaData(TopMeta)); - } - } + SetOpen(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, !IsOpen(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ)); } } ; From 376d5e7ff0d2daab13aee0bf184a3ef5375bd1e6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 30 May 2014 22:31:51 +0200 Subject: [PATCH 188/312] Initial commit of the Generator article. --- docs/Generator.html | 119 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 docs/Generator.html diff --git a/docs/Generator.html b/docs/Generator.html new file mode 100644 index 000000000..f71ce1c71 --- /dev/null +++ b/docs/Generator.html @@ -0,0 +1,119 @@ + + +Generating terrain in MCServer + + +

Generating terrain in MCServer

+

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.

+ +

Preface: How it's done in real life

+

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.

+

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.

+ +

Expected properties

+

For a MineCraft-like game terrain generator we need the generator to have several properties: +

    +
  • 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.
  • +
  • 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.
  • +
  • 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.
  • +
+

+ +

Reversing the flow

+

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.

+

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.

+ +

The ComposableGenerator pipeline

+

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: +

    +
  • Biomes
  • +
  • Terrain height
  • +
  • Terrain composition
  • +
  • Finishers
  • +
+

+ + + + +

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. +

+ +

Using coherent noise for the generation

+

For a great tutorial on coherent noise, see the LibNoise +documentation.

+

Coherent noise is a type of noise that has three important properties that we can use to our advantage: +

    +
  • The noise is smooth
  • +
  • The noise is algorithmically generated, which means that the same data is generated when the same +parameters are given to the noise functions.
  • +
  • The noise can be seamlessly extended in any direction
  • +

+

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:

+ +

It comes only naturally that such a 2D noise can be used as a terrain height map directly:

+ +

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.

+ +

Generating biomes

+

The easiest way to generate biomes is to not generate 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.

+

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 biomes.

+

Voronoi diagram

+

These two generators are 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 +Voronoi diagram 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:

+ +

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.

+

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]:

+ +

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 5 x 5 seeds around it:

+ + + From 8bf7aed67cb59edd72662114244da5c1cf5f2140 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 30 May 2014 22:40:19 +0200 Subject: [PATCH 189/312] Updated PlainsVillage and AlchemistVillage. --- .../Prefabs/AlchemistVillagePrefabs.cpp | 603 ++++++++---- .../Prefabs/PlainsVillagePrefabs.cpp | 906 +++++++++++++++++- 2 files changed, 1270 insertions(+), 239 deletions(-) diff --git a/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp index 32ffe5b88..6e3f82212 100644 --- a/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp +++ b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp @@ -20,24 +20,25 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = // The data has been exported from the gallery Desert, area index 82, ID 598, created by STR_Warrior { // Size: - 11, 12, 9, // SizeX = 11, SizeY = 12, SizeZ = 9 + 11, 12, 10, // SizeX = 11, SizeY = 12, SizeZ = 10 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 10, 11, 8, // MaxX, MaxY, MaxZ + 10, 11, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "A:101: 0\n" /* ironbars */ - "B: 64:12\n" /* wooddoorblock */ - "C:128: 2\n" /* sandstonestairs */ - "D: 24: 1\n" /* sandstone */ - "E: 44: 9\n" /* step */ - "F:126: 8\n" /* woodenslab */ - "G:128: 7\n" /* sandstonestairs */ - "H: 44: 1\n" /* step */ - "I: 64: 7\n" /* wooddoorblock */ - "J:128: 6\n" /* sandstonestairs */ + "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 */ @@ -62,8 +63,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "v:134: 7\n" /* 134 */ "w:107: 5\n" /* fencegate */ "x: 64: 5\n" /* wooddoorblock */ - "y: 50: 3\n" /* torch */ - "z:171: 8\n" /* carpet */, + "y: 65: 3\n" /* ladder */ + "z: 50: 3\n" /* torch */, // Block data: // Level 0 @@ -78,6 +79,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 6 */ "aabbbbbbbaa" /* 7 */ "aabbbbbbbaa" /* 8 */ "aaaaaaaaaaa" + /* 9 */ "aaaaaaaaaaa" // Level 1 /* z\x* 1 */ @@ -91,6 +93,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 6 */ "cb.......bc" /* 7 */ "cbg......bc" /* 8 */ "cbbbbbbbbbc" + /* 9 */ "ccccccccccc" // Level 2 /* z\x* 1 */ @@ -104,6 +107,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 6 */ "cb.......bc" /* 7 */ "cbg......bc" /* 8 */ "cbbbbbbbbbc" + /* 9 */ "ccccccccccc" // Level 3 /* z\x* 1 */ @@ -117,6 +121,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 6 */ "cb.......bc" /* 7 */ "cbg..l...bc" /* 8 */ "cbbbbbbbbbc" + /* 9 */ "ccccccccccc" // Level 4 /* z\x* 1 */ @@ -130,6 +135,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 6 */ "cnnnnnnnnnc" /* 7 */ "cnonnnnnnnc" /* 8 */ "cnccccccccc" + /* 9 */ "ccccccccccc" // Level 5 /* z\x* 1 */ @@ -143,6 +149,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 6 */ "bfvvd.....b" /* 7 */ "b...w..kujb" /* 8 */ "pxbbbbbbbbp" + /* 9 */ "..y........" // Level 6 /* z\x* 1 */ @@ -150,38 +157,41 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "...p...p..." /* 1 */ "..........." /* 2 */ "pbbb...bbbp" - /* 3 */ "b..y...y..b" - /* 4 */ "b.z.....z.b" - /* 5 */ "A.........A" + /* 3 */ "b..z...z..b" + /* 4 */ "b.A.....A.b" + /* 5 */ "B.........B" /* 6 */ "b.........b" - /* 7 */ "b.......z.b" - /* 8 */ "pBbbAAAbbbp" + /* 7 */ "b.......A.b" + /* 8 */ "pCbbBBBbbbp" + /* 9 */ "..y........" // Level 7 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "...C...C..." - /* 1 */ "...D...b..." - /* 2 */ "pbbbqEsbbbp" - /* 3 */ "bFFFFFFFFFb" - /* 4 */ "bFFFFFFFFFb" - /* 5 */ "sFFFFFFFFFq" - /* 6 */ "bFFFFFFFFFb" - /* 7 */ "bFFFFFFFFFb" - /* 8 */ "pbbbGGGbbbp" + /* 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 */ "bHHHHbHHHHb" - /* 3 */ "HpbbbbbbbpH" - /* 4 */ "Hb.......bH" + /* 2 */ "bIIIIbIIIIb" + /* 3 */ "IpbbbbbbbpI" + /* 4 */ "Ib.......bI" /* 5 */ "bb.......bb" - /* 6 */ "Hb.......bH" - /* 7 */ "HpIbbbbbbpH" - /* 8 */ "bH.HHbHHHHb" + /* 6 */ "Ib.......bI" + /* 7 */ "IpJbbbbbbpI" + /* 8 */ "bI.IIbIIIIb" + /* 9 */ "..........." // Level 9 /* z\x* 1 */ @@ -189,12 +199,13 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..........." /* 1 */ "..........." /* 2 */ "..........." - /* 3 */ ".pbbAAAbbp." + /* 3 */ ".pbbBBBbbp." /* 4 */ ".b.......b." - /* 5 */ ".A.......A." + /* 5 */ ".B.......B." /* 6 */ ".b.......b." - /* 7 */ ".pBbAAAbbp." + /* 7 */ ".pCbBBBbbp." /* 8 */ "..........." + /* 9 */ "..........." // Level 10 /* z\x* 1 */ @@ -202,12 +213,13 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..........." /* 1 */ "..........." /* 2 */ "..........." - /* 3 */ ".pbbJJJbbp." - /* 4 */ ".bFFFFFFFb." - /* 5 */ ".sFFFFFFFq." - /* 6 */ ".bFFFFFFFb." - /* 7 */ ".pbbGGGbbp." + /* 3 */ ".pbbKKKbbp." + /* 4 */ ".bGGGGGGGb." + /* 5 */ ".sGGGGGGGq." + /* 6 */ ".bGGGGGGGb." + /* 7 */ ".pbbHHHbbp." /* 8 */ "..........." + /* 9 */ "..........." // Level 11 /* z\x* 1 */ @@ -215,12 +227,13 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..........." /* 1 */ "..........." /* 2 */ "..........." - /* 3 */ ".bHHHbHHHb." - /* 4 */ ".H.......H." + /* 3 */ ".bIIIbIIIb." + /* 4 */ ".I.......I." /* 5 */ ".b.......b." - /* 6 */ ".H.......H." - /* 7 */ ".bHHHbHHHb." - /* 8 */ "...........", + /* 6 */ ".I.......I." + /* 7 */ ".bIIIbIIIb." + /* 8 */ "..........." + /* 9 */ "...........", // Connectors: "-1: 5, 5, 0: 2\n" /* Type -1, direction Z- */, @@ -235,7 +248,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = true, // DefaultWeight: - 100, + 70, // DepthWeight: "", @@ -254,18 +267,19 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = // The data has been exported from the gallery Desert, area index 81, ID 597, created by STR_Warrior { // Size: - 11, 8, 9, // SizeX = 11, SizeY = 8, SizeZ = 9 + 11, 8, 10, // SizeX = 11, SizeY = 8, SizeZ = 10 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 10, 7, 8, // MaxX, MaxY, MaxZ + 10, 7, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "A: 44: 1\n" /* step */ - "B: 64: 3\n" /* wooddoorblock */ - "C: 64: 8\n" /* wooddoorblock */ - "D:128: 6\n" /* sandstonestairs */ + "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 */ @@ -283,15 +297,15 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "o:134: 4\n" /* 134 */ "p:107: 5\n" /* fencegate */ "q: 64: 5\n" /* wooddoorblock */ - "r: 50: 3\n" /* torch */ - "s:171: 8\n" /* carpet */ - "t:101: 0\n" /* ironbars */ - "u: 64:12\n" /* wooddoorblock */ - "v:128: 2\n" /* sandstonestairs */ - "w: 24: 1\n" /* sandstone */ - "x: 44: 9\n" /* step */ - "y:126: 8\n" /* woodenslab */ - "z:128: 7\n" /* sandstonestairs */, + "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 @@ -306,6 +320,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 6 */ "abbbbbbbbba" /* 7 */ "abbbbbbbbba" /* 8 */ "abaaaaaaaaa" + /* 9 */ "aaaaaaaaaaa" // Level 1 /* z\x* 1 */ @@ -319,6 +334,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 6 */ "dlnno.....d" /* 7 */ "d...p..hjkd" /* 8 */ "cqddddddddc" + /* 9 */ "..r........" // Level 2 /* z\x* 1 */ @@ -326,38 +342,41 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "...c...c..." /* 1 */ "..........." /* 2 */ "cddd...dddc" - /* 3 */ "d..r...r..d" - /* 4 */ "d.s.....s.d" - /* 5 */ "t.........t" + /* 3 */ "d..s...s..d" + /* 4 */ "d.t.....t.d" + /* 5 */ "u.........u" /* 6 */ "d.........d" - /* 7 */ "d.......s.d" - /* 8 */ "cuddtttdddc" + /* 7 */ "d.......t.d" + /* 8 */ "cvdduuudddc" + /* 9 */ "..r........" // Level 3 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "...v...v..." - /* 1 */ "...w...d..." - /* 2 */ "cdddexgdddc" - /* 3 */ "dyyyyyyyyyd" - /* 4 */ "dyyyyyyyyyd" - /* 5 */ "gyyyyyyyyye" - /* 6 */ "dyyyyyyyyyd" - /* 7 */ "dyyyyyyyyyd" - /* 8 */ "cdddzzzdddc" + /* 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 */ "dAAAAdAAAAd" - /* 3 */ "AcdddddddcA" - /* 4 */ "Ad.......dA" + /* 2 */ "dBBBBdBBBBd" + /* 3 */ "BcdddddddcB" + /* 4 */ "Bd.......dB" /* 5 */ "dd.......dd" - /* 6 */ "Ad.......dA" - /* 7 */ "AcBddddddcA" - /* 8 */ "dA.AAdAAAAd" + /* 6 */ "Bd.......dB" + /* 7 */ "BcCddddddcB" + /* 8 */ "dB.BBdBBBBd" + /* 9 */ "..........." // Level 5 /* z\x* 1 */ @@ -365,12 +384,13 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..........." /* 1 */ "..........." /* 2 */ "..........." - /* 3 */ ".cddtttddc." + /* 3 */ ".cdduuuddc." /* 4 */ ".d.......d." - /* 5 */ ".t.......t." + /* 5 */ ".u.......u." /* 6 */ ".d.......d." - /* 7 */ ".cCdtttddc." + /* 7 */ ".cDduuuddc." /* 8 */ "..........." + /* 9 */ "..........." // Level 6 /* z\x* 1 */ @@ -378,12 +398,13 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..........." /* 1 */ "..........." /* 2 */ "..........." - /* 3 */ ".cddDDDddc." - /* 4 */ ".dyyyyyyyd." - /* 5 */ ".gyyyyyyye." - /* 6 */ ".dyyyyyyyd." - /* 7 */ ".cddzzzddc." + /* 3 */ ".cddEEEddc." + /* 4 */ ".dzzzzzzzd." + /* 5 */ ".gzzzzzzze." + /* 6 */ ".dzzzzzzzd." + /* 7 */ ".cddAAAddc." /* 8 */ "..........." + /* 9 */ "..........." // Level 7 /* z\x* 1 */ @@ -391,12 +412,13 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..........." /* 1 */ "..........." /* 2 */ "..........." - /* 3 */ ".dAAAdAAAd." - /* 4 */ ".A.......A." + /* 3 */ ".dBBBdBBBd." + /* 4 */ ".B.......B." /* 5 */ ".d.......d." - /* 6 */ ".A.......A." - /* 7 */ ".dAAAdAAAd." - /* 8 */ "...........", + /* 6 */ ".B.......B." + /* 7 */ ".dBBBdBBBd." + /* 8 */ "..........." + /* 9 */ "...........", // Connectors: "-1: 5, 1, 0: 2\n" /* Type -1, direction Z- */, @@ -411,7 +433,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = true, // DefaultWeight: - 100, + 80, // DepthWeight: "", @@ -427,7 +449,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // BlackSmith: - // The data has been exported from the gallery Desert, area index 92, ID 633, created by STR_Warrior + // 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 @@ -460,7 +482,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "t:128: 4\n" /* sandstonestairs */ "u:128: 5\n" /* sandstonestairs */ "v:128: 7\n" /* sandstonestairs */ - "w: 44: 1\n" /* step */, + "w: 44: 1\n" /* step */ + "x: 43: 1\n" /* doubleslab */, // Block data: // Level 0 @@ -469,7 +492,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "aaaaaaaaaaa" /* 1 */ "aaaaaaaaaaa" /* 2 */ "aaaaaaaabaa" - /* 3 */ "acaaacabbba" + /* 3 */ "acacacabbba" /* 4 */ "acaccaabbba" /* 5 */ "acccccabbba" /* 6 */ "acaadddbbba" @@ -487,9 +510,9 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 1 */ "..........." /* 2 */ "......dcecd" /* 3 */ ".d....c...c" - /* 4 */ "......c...c" - /* 5 */ "...f..c...c" - /* 6 */ ".....dc...c" + /* 4 */ "..f...c...c" + /* 5 */ "......c...c" + /* 6 */ "....ddc...c" /* 7 */ ".gh.dic...c" /* 8 */ "dcccccd...c" /* 9 */ "cj........c" @@ -506,8 +529,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 3 */ ".d....c..lc" /* 4 */ "......n...c" /* 5 */ "......c...c" - /* 6 */ "......c...n" - /* 7 */ "......c...n" + /* 6 */ "....nnc...n" + /* 7 */ "....n.c...n" /* 8 */ "dcccccd...n" /* 9 */ "co........c" /* 10 */ "n.........c" @@ -523,8 +546,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 3 */ ".drrrrcsssc" /* 4 */ ".rsssstsssc" /* 5 */ ".rsssscsssc" - /* 6 */ ".rsssscsssu" - /* 7 */ ".rsssscsssu" + /* 6 */ ".rssddcsssu" + /* 7 */ ".rssd.csssu" /* 8 */ "dcccccdsssu" /* 9 */ "csssssssssc" /* 10 */ "tsssssssssc" @@ -540,9 +563,9 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 3 */ ".w.w.ww...w" /* 4 */ "......w...w" /* 5 */ ".w....w...w" - /* 6 */ "......w...w" - /* 7 */ ".w....w...c" - /* 8 */ "cwwwwwc...w" + /* 6 */ "....xwx...w" + /* 7 */ ".w..w.w...c" + /* 8 */ "cwwwxwc...w" /* 9 */ "w.........w" /* 10 */ "w.........w" /* 11 */ "w.........w" @@ -561,7 +584,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = true, // DefaultWeight: - 100, + 50, // DepthWeight: "", @@ -588,12 +611,14 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = // Block definitions: ".: 0: 0\n" /* air */ - "A:128: 2\n" /* sandstonestairs */ - "B:128: 0\n" /* sandstonestairs */ - "C: 87: 0\n" /* netherstone */ - "D:128: 3\n" /* sandstonestairs */ - "E: 51: 0\n" /* fire */ - "F: 44: 9\n" /* step */ + "A:128: 7\n" /* sandstonestairs */ + "B: 44: 1\n" /* step */ + "C:128: 2\n" /* sandstonestairs */ + "D:128: 0\n" /* sandstonestairs */ + "E: 87: 0\n" /* netherstone */ + "F:128: 3\n" /* sandstonestairs */ + "G: 51: 0\n" /* fire */ + "H: 44: 9\n" /* step */ "a: 12: 0\n" /* sand */ "b: 5: 0\n" /* wood */ "c: 24: 2\n" /* sandstone */ @@ -610,16 +635,16 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "n:101: 0\n" /* ironbars */ "o:140: 0\n" /* flowerpotblock */ "p: 64: 8\n" /* wooddoorblock */ - "q: 69:12\n" /* lever */ - "r: 44:10\n" /* step */ - "s:128: 1\n" /* sandstonestairs */ - "t: 47: 0\n" /* bookshelf */ - "u: 96:12\n" /* trapdoor */ - "v:128: 4\n" /* sandstonestairs */ - "w:128: 5\n" /* sandstonestairs */ - "x:128: 7\n" /* sandstonestairs */ - "y: 44: 1\n" /* step */ - "z:128: 6\n" /* sandstonestairs */, + "q: 50: 3\n" /* torch */ + "r: 69:12\n" /* lever */ + "s: 50: 4\n" /* torch */ + "t:128: 6\n" /* sandstonestairs */ + "u: 44:10\n" /* step */ + "v:128: 1\n" /* sandstonestairs */ + "w: 47: 0\n" /* bookshelf */ + "x: 96:12\n" /* trapdoor */ + "y:128: 4\n" /* sandstonestairs */ + "z:128: 5\n" /* sandstonestairs */, // Block data: // Level 0 @@ -657,9 +682,9 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* * 012345678901234 */ /* 0 */ "....cddnnnddc.." /* 1 */ "....d......od.c" - /* 2 */ "....p.......d.." + /* 2 */ "....p.......d.q" /* 3 */ "....d.......p.." - /* 4 */ "....d.q...l.d.." + /* 4 */ "....d.r...l.d.s" /* 5 */ "....dddd.dddd.c" /* 6 */ "....n.......n.." /* 7 */ "mmmmn.......n.." @@ -670,32 +695,32 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = // Level 3 /* z\x* 11111 */ /* * 012345678901234 */ - /* 0 */ "....cdddddddc.." - /* 1 */ "....drrrrrrrdds" - /* 2 */ "....drrrrrrrd.." - /* 3 */ "....drrrrrrrd.." - /* 4 */ "....dtttrrurd.." - /* 5 */ "....dddddddddds" - /* 6 */ "....vrrrrrrrw.." - /* 7 */ "mmmmvrrrrrrrw.." - /* 8 */ "mmmmvrrrrrrrw.." - /* 9 */ "mmmmdrrrrrrrd.." - /* 10 */ "mmmmcddxxxddc.." + /* 0 */ "....cddtttddc.." + /* 1 */ "....duuuuuuuddv" + /* 2 */ "....duuuuuuud.." + /* 3 */ "....duuuuuuud.." + /* 4 */ "....dwwwuuxud.." + /* 5 */ "....ddddddddddv" + /* 6 */ "....yuuuuuuuz.." + /* 7 */ "mmmmyuuuuuuuz.." + /* 8 */ "mmmmyuuuuuuuz.." + /* 9 */ "mmmmduuuuuuud.." + /* 10 */ "mmmmcddAAAddc.." // Level 4 /* z\x* 11111 */ /* * 012345678901234 */ - /* 0 */ "....dyyydyyyd.." - /* 1 */ "....ycdddddcy.." - /* 2 */ "....yd.....dy.." - /* 3 */ "....yd.....dy.." - /* 4 */ "....yd.....dy.." + /* 0 */ "....dBBBdBBBd.." + /* 1 */ "....BcdddddcB.." + /* 2 */ "....Bd.....dB.." + /* 3 */ "....Bd.....dB.." + /* 4 */ "....Bd.....dB.." /* 5 */ "....dcdd.ddcd.." - /* 6 */ "....y.......y.." - /* 7 */ "mmmmy.......y.." - /* 8 */ "mmmmy.......y.." - /* 9 */ "mmmmy.......y.." - /* 10 */ "mmmmdyyydyyyd.." + /* 6 */ "....B.......B.." + /* 7 */ "mmmmB.......B.." + /* 8 */ "mmmmB.......B.." + /* 9 */ "mmmmB.......B.." + /* 10 */ "mmmmdBBBdBBBd.." // Level 5 /* z\x* 11111 */ @@ -716,10 +741,10 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* z\x* 11111 */ /* * 012345678901234 */ /* 0 */ "..............." - /* 1 */ ".....cddzddc..." - /* 2 */ ".....vrrrrrw..." - /* 3 */ ".....vrrrrrw..." - /* 4 */ ".....vrrrrrw..." + /* 1 */ ".....cddtddc..." + /* 2 */ ".....yuuuuuz..." + /* 3 */ ".....yuuuuuz..." + /* 4 */ ".....yuuuuuz..." /* 5 */ ".....cdddddc..." /* 6 */ "..............." /* 7 */ "..............." @@ -731,11 +756,11 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* z\x* 11111 */ /* * 012345678901234 */ /* 0 */ "..............." - /* 1 */ ".....dyydyyd..." - /* 2 */ ".....y.ddd.y..." + /* 1 */ ".....dBBdBBd..." + /* 2 */ ".....B.ddd.B..." /* 3 */ ".....d.ddd.d..." - /* 4 */ ".....y.ddd.y..." - /* 5 */ ".....dyydyyd..." + /* 4 */ ".....B.ddd.B..." + /* 5 */ ".....dBBdBBd..." /* 6 */ "..............." /* 7 */ "..............." /* 8 */ "..............." @@ -747,9 +772,9 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* * 012345678901234 */ /* 0 */ "..............." /* 1 */ "..............." - /* 2 */ ".......cAc....." - /* 3 */ ".......BCs....." - /* 4 */ ".......cDc....." + /* 2 */ ".......cCc....." + /* 3 */ ".......DEv....." + /* 4 */ ".......cFc....." /* 5 */ "..............." /* 6 */ "..............." /* 7 */ "..............." @@ -763,7 +788,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..............." /* 1 */ "..............." /* 2 */ ".......c.c....." - /* 3 */ "........E......" + /* 3 */ "........G......" /* 4 */ ".......c.c....." /* 5 */ "..............." /* 6 */ "..............." @@ -777,9 +802,9 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* * 012345678901234 */ /* 0 */ "..............." /* 1 */ "..............." - /* 2 */ ".......c.c....." - /* 3 */ "..............." - /* 4 */ ".......c.c....." + /* 2 */ ".......ctc....." + /* 3 */ ".......y.z....." + /* 4 */ ".......cAc....." /* 5 */ "..............." /* 6 */ "..............." /* 7 */ "..............." @@ -793,7 +818,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..............." /* 1 */ "..............." /* 2 */ ".......ddd....." - /* 3 */ ".......dFd....." + /* 3 */ ".......dHd....." /* 4 */ ".......ddd....." /* 5 */ "..............." /* 6 */ "..............." @@ -807,9 +832,9 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* * 012345678901234 */ /* 0 */ "..............." /* 1 */ "..............." - /* 2 */ ".......y.y....." + /* 2 */ ".......B.B....." /* 3 */ "..............." - /* 4 */ ".......y.y....." + /* 4 */ ".......B.B....." /* 5 */ "..............." /* 6 */ "..............." /* 7 */ "..............." @@ -830,7 +855,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = true, // DefaultWeight: - 100, + 60, // DepthWeight: "", @@ -1169,7 +1194,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 3 */ "abbbbba" /* 4 */ "abbbbba" /* 5 */ "abbbbba" - /* 6 */ "aaaaaaa" + /* 6 */ "aabaaaa" /* 7 */ "aaaaaaa" /* 8 */ "aaaaaaa" /* 9 */ "aaaaaaa" @@ -1384,7 +1409,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "b: 5: 0\n" /* wood */ "c: 24: 2\n" /* sandstone */ "d: 24: 0\n" /* sandstone */ - "e: 64: 3\n" /* wooddoorblock */ + "e: 64: 7\n" /* wooddoorblock */ "f: 65: 5\n" /* ladder */ "g:134: 3\n" /* 134 */ "h: 85: 0\n" /* fence */ @@ -1393,16 +1418,17 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "k:134: 6\n" /* 134 */ "l:134: 4\n" /* 134 */ "m: 19: 0\n" /* sponge */ - "n: 64: 8\n" /* wooddoorblock */ + "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: 5\n" /* sandstonestairs */ - "u:128: 7\n" /* sandstonestairs */ - "v: 44: 1\n" /* step */ - "w: 96: 7\n" /* trapdoor */, + "t:128: 4\n" /* sandstonestairs */ + "u:128: 5\n" /* sandstonestairs */ + "v:128: 7\n" /* sandstonestairs */ + "w: 44: 1\n" /* step */ + "x: 96: 7\n" /* trapdoor */, // Block data: // Level 0 @@ -1454,26 +1480,26 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 2 */ "cdddc" /* 3 */ "dfssd" /* 4 */ "dsssd" - /* 5 */ "tssst" - /* 6 */ "tssst" - /* 7 */ "tssst" + /* 5 */ "tsssu" + /* 6 */ "tsssu" + /* 7 */ "tsssu" /* 8 */ "dsssd" /* 9 */ "dsssd" - /* 10 */ "cdudc" + /* 10 */ "cdvdc" // Level 4 /* z\x* 01234 */ /* 0 */ "....." /* 1 */ "....." - /* 2 */ "dvdvd" - /* 3 */ "vw..v" - /* 4 */ "v...v" - /* 5 */ "v...v" + /* 2 */ "dwdwd" + /* 3 */ "wx..w" + /* 4 */ "w...w" + /* 5 */ "w...w" /* 6 */ "d...d" - /* 7 */ "v...v" - /* 8 */ "v...v" - /* 9 */ "v...v" - /* 10 */ "dvdvd", + /* 7 */ "w...w" + /* 8 */ "w...w" + /* 9 */ "w...w" + /* 10 */ "dwdwd", // Connectors: "-1: 2, 1, 0: 2\n" /* Type -1, direction Z- */, @@ -2050,7 +2076,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "o:128: 4\n" /* sandstonestairs */ "p:128: 7\n" /* sandstonestairs */ "q: 44: 1\n" /* step */ - "r: 50: 3\n" /* torch */, + "r: 50: 3\n" /* torch */ + "s:128: 6\n" /* sandstonestairs */, // Block data: // Level 0 @@ -2137,11 +2164,11 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..............." /* 1 */ "..............." /* 2 */ "..............." - /* 3 */ "...cdddc......." + /* 3 */ "...cdsdc......." /* 4 */ "...dnnnd......." /* 5 */ "...dnnnd......." /* 6 */ "...dnnnd......." - /* 7 */ "...cdddc......." + /* 7 */ "...cdpdc......." /* 8 */ "..............." // Level 7 @@ -2170,7 +2197,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = true, // DefaultWeight: - 100, + 80, // DepthWeight: "", @@ -2364,7 +2391,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = true, // DefaultWeight: - 100, + 80, // DepthWeight: "", @@ -2582,7 +2609,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = true, // DefaultWeight: - 100, + 80, // DepthWeight: "", @@ -2690,7 +2717,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* z\x* 012345678 */ /* 0 */ "mmmm....." /* 1 */ "mmmm....." - /* 2 */ "mmmmcrdrd" + /* 2 */ "mmmmdrdrd" /* 3 */ "mmmmr...r" /* 4 */ "mmmmr...r" /* 5 */ "mmmmr...r" @@ -2724,6 +2751,192 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = // 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): + 0, 0, 0, // MinX, MinY, MinZ + 12, 8, 8, // 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 diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp index f8cf867e5..f5e531955 100644 --- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -797,8 +797,9 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = ".: 0: 0\n" /* air */ "a: 5: 0\n" /* wood */ "b: 85: 0\n" /* fence */ - "c: 50: 2\n" /* torch */ - "d: 50: 1\n" /* torch */ + "c: 66: 1\n" /* tracks */ + "d: 50: 2\n" /* torch */ + "e: 50: 1\n" /* torch */ "m: 19: 0\n" /* sponge */, // Block data: @@ -813,7 +814,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* z\x* */ /* * 0123456789 */ /* 0 */ "..b....b.." - /* 1 */ ".........." + /* 1 */ "cccccccccc" /* 2 */ "..b....b.." // Level 2 @@ -827,14 +828,12 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* z\x* */ /* * 0123456789 */ /* 0 */ "..a....a.." - /* 1 */ ".cad..cad." + /* 1 */ ".dae..dae." /* 2 */ "..a....a..", // Connectors: "-3: 0, 1, 1: 4\n" /* Type -3, direction X- */ - "3: 0, 1, 1: 4\n" /* Type 3, direction X- */ - "3: 9, 1, 1: 5\n" /* Type 3, direction X+ */ - "-3: 9, 1, 1: 5\n" /* Type -3, direction X+ */, + "3: 9, 1, 1: 5\n" /* Type 3, direction X+ */, // AllowedRotations: 7, /* 1, 2, 3 CCW rotation allowed */ @@ -874,6 +873,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // 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: @@ -887,11 +888,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 1 /* z\x* 01234 */ - /* 0 */ "m...m" - /* 1 */ ".a.a." - /* 2 */ "....." - /* 3 */ ".a.a." - /* 4 */ "m...m" + /* 0 */ "m.b.m" + /* 1 */ ".aba." + /* 2 */ "ccccc" + /* 3 */ ".aba." + /* 4 */ "m.b.m" // Level 2 /* z\x* 01234 */ @@ -929,7 +930,125 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = false, // DefaultWeight: - 5, + 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: "", @@ -957,6 +1076,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // 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: @@ -970,11 +1091,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 1 /* z\x* 01234 */ - /* 0 */ "m...m" - /* 1 */ ".a.a." - /* 2 */ "....." - /* 3 */ ".a.a." - /* 4 */ "m...m" + /* 0 */ "m.b.m" + /* 1 */ ".aba." + /* 2 */ "ccccc" + /* 3 */ ".aba." + /* 4 */ "m.b.m" // Level 2 /* z\x* 01234 */ @@ -1052,7 +1173,7 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = false, // DefaultWeight: - 5, + 1, // DepthWeight: "", @@ -1066,6 +1187,703 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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, 11, // SizeX = 11, SizeY = 12, SizeZ = 11 + + // Hitbox (relative to bounding box): + 0, 0, 0, // MinX, MinY, MinZ + 10, 11, 10, // MaxX, MaxY, MaxZ + + // Block definitions: + ".: 0: 0\n" /* air */ + "a: 5: 0\n" /* wood */ + "b: 66: 5\n" /* tracks */ + "c: 85: 0\n" /* fence */ + "d: 66: 0\n" /* tracks */ + "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 */ "mmmmmmmmmmm" + /* 3 */ "mmmmmmmmmmm" + /* 4 */ "mmmmmmmmmmm" + /* 5 */ "mmmmmmmmmmm" + /* 6 */ "mmmmmmmmmmm" + /* 7 */ "mmmmmmmmmmm" + /* 8 */ "mmmmmmmmmmm" + /* 9 */ "mmmmmmmmmmm" + /* 10 */ "mmmmmmmmmmm" + + // Level 1 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmm.b.mmmm" + /* 1 */ "mmmmaaammmm" + /* 2 */ "mmmmaaammmm" + /* 3 */ "mmmmmmmmmmm" + /* 4 */ "mmmmmmmmmmm" + /* 5 */ "mmmmmmmmmmm" + /* 6 */ "mmmmmmmmmmm" + /* 7 */ "mmmmmmmmmmm" + /* 8 */ "mmmmmmmmmmm" + /* 9 */ "mmmmmmmmmmm" + /* 10 */ "mmmmmmmmmmm" + + // Level 2 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmm...mmmm" + /* 1 */ "mmmm.b.mmmm" + /* 2 */ "mmmmaaammmm" + /* 3 */ "mmmmaaammmm" + /* 4 */ "mmmmmmmmmmm" + /* 5 */ "mmmmmmmmmmm" + /* 6 */ "mmmmmmmmmmm" + /* 7 */ "mmmmmmmmmmm" + /* 8 */ "mmmmmmmmmmm" + /* 9 */ "mmmmmmmmmmm" + /* 10 */ "mmmmmmmmmmm" + + // Level 3 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmm...mmmm" + /* 1 */ "mmmm...mmmm" + /* 2 */ "mmmmcbcmmmm" + /* 3 */ "mmmmaaammmm" + /* 4 */ "mmmmaaammmm" + /* 5 */ "mmmmmmmmmmm" + /* 6 */ "mmmmmmmmmmm" + /* 7 */ "mmmmmmmmmmm" + /* 8 */ "mmmmmmmmmmm" + /* 9 */ "mmmmmmmmmmm" + /* 10 */ "mmmmmmmmmmm" + + // Level 4 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmm...mmmm" + /* 1 */ "mmmm...mmmm" + /* 2 */ "mmmmc.cmmmm" + /* 3 */ "mmmm.b.mmmm" + /* 4 */ "aaaaaaaaaaa" + /* 5 */ "aaaaaaaaaaa" + /* 6 */ "aaaaaaaaaaa" + /* 7 */ "mmmmaaammmm" + /* 8 */ "mmmmmmmmmmm" + /* 9 */ "mmmmmmmmmmm" + /* 10 */ "mmmmmmmmmmm" + + // Level 5 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmmmmmmmmm" + /* 1 */ "mmmm...mmmm" + /* 2 */ "mmmmc.cmmmm" + /* 3 */ "mmmm...mmmm" + /* 4 */ "..c..d..c.." + /* 5 */ "eeeeeeeeeee" + /* 6 */ "..c..b..c.." + /* 7 */ "mmmmaaammmm" + /* 8 */ "mmmmaaammmm" + /* 9 */ "mmmmmmmmmmm" + /* 10 */ "mmmmmmmmmmm" + + // Level 6 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmmmmmmmmm" + /* 1 */ "mmmmmmmmmmm" + /* 2 */ "mmmmc.cmmmm" + /* 3 */ "mmmm...mmmm" + /* 4 */ "..c.....c.." + /* 5 */ "..........." + /* 6 */ "..c.....c.." + /* 7 */ "mmmm.b.mmmm" + /* 8 */ "mmmmaaammmm" + /* 9 */ "mmmmaaammmm" + /* 10 */ "mmmmmmmmmmm" + + // Level 7 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmmmmmmmmm" + /* 1 */ "mmmmmmmmmmm" + /* 2 */ "mmmmaaammmm" + /* 3 */ "mmmm.f.mmmm" + /* 4 */ "..a.....a.." + /* 5 */ ".gah...gah." + /* 6 */ "..a.....a.." + /* 7 */ "mmmm...mmmm" + /* 8 */ "mmmmcbcmmmm" + /* 9 */ "mmmmaaammmm" + /* 10 */ "mmmmaaammmm" + + // Level 8 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmmmmmmmmm" + /* 1 */ "mmmmmmmmmmm" + /* 2 */ "mmmmmmmmmmm" + /* 3 */ "mmmmmmmmmmm" + /* 4 */ "mmmmmmmmmmm" + /* 5 */ "mmmmmmmmmmm" + /* 6 */ "mmmm...mmmm" + /* 7 */ "mmmm...mmmm" + /* 8 */ "mmmmc.cmmmm" + /* 9 */ "mmmm.b.mmmm" + /* 10 */ "mmmmaaammmm" + + // Level 9 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmmmmmmmmm" + /* 1 */ "mmmmmmmmmmm" + /* 2 */ "mmmmmmmmmmm" + /* 3 */ "mmmmmmmmmmm" + /* 4 */ "mmmmmmmmmmm" + /* 5 */ "mmmmmmmmmmm" + /* 6 */ "mmmmmmmmmmm" + /* 7 */ "mmmm...mmmm" + /* 8 */ "mmmmc.cmmmm" + /* 9 */ "mmmm...mmmm" + /* 10 */ "mmmm.d.mmmm" + + // Level 10 + /* z\x* 1 */ + /* * 01234567890 */ + /* 0 */ "mmmmmmmmmmm" + /* 1 */ "mmmmmmmmmmm" + /* 2 */ "mmmmmmmmmmm" + /* 3 */ "mmmmmmmmmmm" + /* 4 */ "mmmmmmmmmmm" + /* 5 */ "mmmmmmmmmmm" + /* 6 */ "mmmmmmmmmmm" + /* 7 */ "mmmmmmmmmmm" + /* 8 */ "mmmmc.cmmmm" + /* 9 */ "mmmm...mmmm" + /* 10 */ "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 */ "mmmmaaammmm" + /* 9 */ "mmmm.f.mmmm" + /* 10 */ "mmmm...mmmm", + + // Connectors: + "3: 0, 5, 5: 4\n" /* Type 3, direction X- */ + "-3: 0, 5, 5: 4\n" /* Type -3, direction X- */ + "3: 10, 5, 5: 5\n" /* Type 3, direction X+ */ + "-3: 10, 5, 5: 5\n" /* Type -3, direction X+ */ + "3: 5, 9, 10: 3\n" /* Type 3, direction Z+ */ + "-3: 5, 9, 10: 3\n" /* Type -3, direction Z+ */ + "3: 5, 1, 0: 2\n" /* Type 3, direction Z- */ + "-3: 5, 1, 0: 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 @@ -2770,8 +3588,8 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Block definitions: ".: 0: 0\n" /* air */ - "a: 3: 0\n" /* dirt */ - "b: 2: 0\n" /* grass */ + "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 */ @@ -2796,19 +3614,19 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 0 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "abaaaaabbbb" - /* 1 */ "baaaaaaaaab" - /* 2 */ "baaaaaaaaab" - /* 3 */ "baaaaaaaaab" - /* 4 */ "baaaaaaaaab" - /* 5 */ "baaaaaaaaab" - /* 6 */ "baaaaaaaaab" - /* 7 */ "baaaaaaaaab" - /* 8 */ "bbaaaaaaabb" - /* 9 */ "bbaaaaaaabb" - /* 10 */ "bbaaaaaaabb" - /* 11 */ "bbaaaaaaabb" - /* 12 */ "bbaaaaaaabb" + /* 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 */ @@ -2821,11 +3639,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 5 */ "mcccccccccm" /* 6 */ "mcccccccccm" /* 7 */ "mcccccccccm" - /* 8 */ "mmaaaaaaamm" - /* 9 */ "mmaaaaaaamm" - /* 10 */ "mmaaaaaaamm" - /* 11 */ "mmaaaaaaamm" - /* 12 */ "mmaaaaaaamm" + /* 8 */ "mmbbbbbbbmm" + /* 9 */ "mmbbbbbbbmm" + /* 10 */ "mmbbbbbbbmm" + /* 11 */ "mmbbbbbbbmm" + /* 12 */ "mmbbbbbbbmm" // Level 2 /* z\x* 1 */ @@ -2838,11 +3656,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 5 */ ".cggggcccc." /* 6 */ ".cggggcccc." /* 7 */ ".ccccccccc." - /* 8 */ "..bbbbbbb.." - /* 9 */ "..bbbbbbb.." - /* 10 */ "..bbbbbbb.." - /* 11 */ "..bbbbbbb.." - /* 12 */ "..bbbbbbb.." + /* 8 */ "..aaaaaaa.." + /* 9 */ "..aaaaaaa.." + /* 10 */ "..aaaaaaa.." + /* 11 */ "..aaaaaaa.." + /* 12 */ "..aaaaaaa.." // Level 3 /* z\x* 1 */ From b9d306a801af7de6c620740d5f8c827c7df29dce Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 30 May 2014 22:41:47 +0200 Subject: [PATCH 190/312] Fixed bindings for cCompositeChat:SetMessageType(). --- src/Bindings/ManualBindings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 10e560ac0..14d9d16fc 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -2864,8 +2864,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: From 843288493e1dcf9e22ac644d652ea3b13c7858ab Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 30 May 2014 23:41:17 +0200 Subject: [PATCH 191/312] Fix the furnace result slot. --- src/UI/SlotArea.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 507b45833..6853ff90c 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1381,14 +1381,99 @@ 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; + } + + if (a_ClickAction == caDblClick) + { + return; + } + + if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick)) + { + ShiftClicked(a_Player, a_SlotNum, a_ClickedItem); + } + + cItem Slot(*GetSlot(a_SlotNum, a_Player)); + if (!Slot.IsSameType(a_ClickedItem)) + { + LOGWARNING("*** Window lost sync at item %d in SlotArea with %d items ***", a_SlotNum, m_NumSlots); + LOGWARNING("My item: %s", ItemToFullString(Slot).c_str()); + LOGWARNING("Their item: %s", ItemToFullString(a_ClickedItem).c_str()); + bAsync = true; + } + cItem & DraggingItem = a_Player.GetDraggingItem(); + + if (!DraggingItem.IsEmpty()) + { + if (!DraggingItem.IsEqual(Slot)) + { + return; + } + if ((DraggingItem.m_ItemCount + Slot.m_ItemCount) > Slot.GetMaxStackSize()) + { + return; + } + + DraggingItem.m_ItemCount += Slot.m_ItemCount; + Slot.Empty(); + } + else + { + switch (a_ClickAction) + { + case caDblClick: + { + DblClicked(a_Player, a_SlotNum); + return; + } + case caLeftClick: + { + DraggingItem = cItem(Slot); + 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.IsEmpty()) + { + Slot.Empty(); + } + 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); } @@ -1397,6 +1482,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 +1493,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 +1503,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())); From 01fc93857cb18d918ab98109dabd9665038871af Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 31 May 2014 00:22:24 +0200 Subject: [PATCH 192/312] Change "Slot.IsEmpty()" to "Slot.m_ItemCount <= 0" --- src/UI/SlotArea.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 6853ff90c..3acc49cde 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1452,7 +1452,7 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a DraggingItem.m_ItemCount = (char)(((float)Slot.m_ItemCount) / 2.f + 0.5f); Slot.m_ItemCount -= DraggingItem.m_ItemCount; - if (Slot.IsEmpty()) + if (Slot.m_ItemCount <= 0) { Slot.Empty(); } From d422aa4081cd5c64ab0df4017630674a245c701d Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 31 May 2014 00:25:20 +0200 Subject: [PATCH 193/312] Fix DBL bug. --- src/UI/SlotArea.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 3acc49cde..7c79e290a 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1397,11 +1397,6 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a return; } - if (a_ClickAction == caDblClick) - { - return; - } - if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick)) { ShiftClicked(a_Player, a_SlotNum, a_ClickedItem); @@ -1419,6 +1414,10 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a if (!DraggingItem.IsEmpty()) { + if (a_ClickAction == caDblClick) + { + return; + } if (!DraggingItem.IsEqual(Slot)) { return; From 2030800ad78678b783224010e22382d413863975 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 31 May 2014 00:27:24 +0200 Subject: [PATCH 194/312] Set DraggingItem to Slot directly. --- src/UI/SlotArea.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index 7c79e290a..b3e126247 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1441,7 +1441,7 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a } case caLeftClick: { - DraggingItem = cItem(Slot); + DraggingItem = Slot; Slot.Empty(); break; } From f4e9c88dcdefee2b6e4ca7f97483d4cdfba939ae Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 31 May 2014 10:33:12 +0200 Subject: [PATCH 195/312] Fixed a memory leak in VillagGen. --- src/Generating/VillageGen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index dfcdf6ef7..b9cb056ad 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -147,6 +147,11 @@ public: } } + ~cVillage() + { + cPieceGenerator::FreePieces(m_Pieces); + } + protected: /** Seed for the random functions */ int m_Seed; From 600c93bdc16e6826ebf9822ad941a1f87139bab5 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 31 May 2014 10:33:29 +0200 Subject: [PATCH 196/312] Updated PlainsVillage prefabs. --- .../Prefabs/PlainsVillagePrefabs.cpp | 182 ++++++++++-------- 1 file changed, 97 insertions(+), 85 deletions(-) diff --git a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp index f5e531955..f5c5b7a20 100644 --- a/src/Generating/Prefabs/PlainsVillagePrefabs.cpp +++ b/src/Generating/Prefabs/PlainsVillagePrefabs.cpp @@ -1472,18 +1472,18 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // The data has been exported from the gallery Plains, area index 199, ID 663, created by Aloe_vera { // Size: - 11, 12, 11, // SizeX = 11, SizeY = 12, SizeZ = 11 + 11, 12, 12, // SizeX = 11, SizeY = 12, SizeZ = 12 // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ - 10, 11, 10, // MaxX, MaxY, MaxZ + 10, 11, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ "a: 5: 0\n" /* wood */ - "b: 66: 5\n" /* tracks */ - "c: 85: 0\n" /* fence */ - "d: 66: 0\n" /* tracks */ + "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 */ @@ -1496,21 +1496,6 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* * 01234567890 */ /* 0 */ "mmmmaaammmm" /* 1 */ "mmmmaaammmm" - /* 2 */ "mmmmmmmmmmm" - /* 3 */ "mmmmmmmmmmm" - /* 4 */ "mmmmmmmmmmm" - /* 5 */ "mmmmmmmmmmm" - /* 6 */ "mmmmmmmmmmm" - /* 7 */ "mmmmmmmmmmm" - /* 8 */ "mmmmmmmmmmm" - /* 9 */ "mmmmmmmmmmm" - /* 10 */ "mmmmmmmmmmm" - - // Level 1 - /* z\x* 1 */ - /* * 01234567890 */ - /* 0 */ "mmmm.b.mmmm" - /* 1 */ "mmmmaaammmm" /* 2 */ "mmmmaaammmm" /* 3 */ "mmmmmmmmmmm" /* 4 */ "mmmmmmmmmmm" @@ -1520,12 +1505,13 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 8 */ "mmmmmmmmmmm" /* 9 */ "mmmmmmmmmmm" /* 10 */ "mmmmmmmmmmm" + /* 11 */ "mmmmmmmmmmm" - // Level 2 + // Level 1 /* z\x* 1 */ /* * 01234567890 */ - /* 0 */ "mmmm...mmmm" - /* 1 */ "mmmm.b.mmmm" + /* 0 */ "mmmm.b.mmmm" + /* 1 */ "mmmm.c.mmmm" /* 2 */ "mmmmaaammmm" /* 3 */ "mmmmaaammmm" /* 4 */ "mmmmmmmmmmm" @@ -1535,13 +1521,14 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 8 */ "mmmmmmmmmmm" /* 9 */ "mmmmmmmmmmm" /* 10 */ "mmmmmmmmmmm" + /* 11 */ "mmmmmmmmmmm" - // Level 3 + // Level 2 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "mmmm...mmmm" /* 1 */ "mmmm...mmmm" - /* 2 */ "mmmmcbcmmmm" + /* 2 */ "mmmm.c.mmmm" /* 3 */ "mmmmaaammmm" /* 4 */ "mmmmaaammmm" /* 5 */ "mmmmmmmmmmm" @@ -1550,66 +1537,87 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 8 */ "mmmmmmmmmmm" /* 9 */ "mmmmmmmmmmm" /* 10 */ "mmmmmmmmmmm" + /* 11 */ "mmmmmmmmmmm" - // Level 4 + // Level 3 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "mmmm...mmmm" /* 1 */ "mmmm...mmmm" - /* 2 */ "mmmmc.cmmmm" - /* 3 */ "mmmm.b.mmmm" - /* 4 */ "aaaaaaaaaaa" - /* 5 */ "aaaaaaaaaaa" - /* 6 */ "aaaaaaaaaaa" - /* 7 */ "mmmmaaammmm" + /* 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 */ "mmmm...mmmm" - /* 2 */ "mmmmc.cmmmm" - /* 3 */ "mmmm...mmmm" - /* 4 */ "..c..d..c.." - /* 5 */ "eeeeeeeeeee" - /* 6 */ "..c..b..c.." - /* 7 */ "mmmmaaammmm" + /* 1 */ "mmmmmmmmmmm" + /* 2 */ "mmmm...mmmm" + /* 3 */ "mmmmd.dmmmm" + /* 4 */ "mmmm...mmmm" + /* 5 */ "..d..b..d.." + /* 6 */ "eeeeeeeeeee" + /* 7 */ "..d..c..d.." /* 8 */ "mmmmaaammmm" - /* 9 */ "mmmmmmmmmmm" + /* 9 */ "mmmmaaammmm" /* 10 */ "mmmmmmmmmmm" + /* 11 */ "mmmmmmmmmmm" // Level 6 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "mmmmmmmmmmm" /* 1 */ "mmmmmmmmmmm" - /* 2 */ "mmmmc.cmmmm" - /* 3 */ "mmmm...mmmm" - /* 4 */ "..c.....c.." - /* 5 */ "..........." - /* 6 */ "..c.....c.." - /* 7 */ "mmmm.b.mmmm" - /* 8 */ "mmmmaaammmm" + /* 2 */ "mmmmmmmmmmm" + /* 3 */ "mmmmd.dmmmm" + /* 4 */ "mmmm...mmmm" + /* 5 */ "..d.....d.." + /* 6 */ "..........." + /* 7 */ "..d.....d.." + /* 8 */ "mmmm.c.mmmm" /* 9 */ "mmmmaaammmm" - /* 10 */ "mmmmmmmmmmm" + /* 10 */ "mmmmaaammmm" + /* 11 */ "mmmmmmmmmmm" // Level 7 /* z\x* 1 */ /* * 01234567890 */ /* 0 */ "mmmmmmmmmmm" /* 1 */ "mmmmmmmmmmm" - /* 2 */ "mmmmaaammmm" - /* 3 */ "mmmm.f.mmmm" - /* 4 */ "..a.....a.." - /* 5 */ ".gah...gah." - /* 6 */ "..a.....a.." - /* 7 */ "mmmm...mmmm" - /* 8 */ "mmmmcbcmmmm" - /* 9 */ "mmmmaaammmm" + /* 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 */ @@ -1620,11 +1628,12 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 3 */ "mmmmmmmmmmm" /* 4 */ "mmmmmmmmmmm" /* 5 */ "mmmmmmmmmmm" - /* 6 */ "mmmm...mmmm" + /* 6 */ "mmmmmmmmmmm" /* 7 */ "mmmm...mmmm" - /* 8 */ "mmmmc.cmmmm" - /* 9 */ "mmmm.b.mmmm" - /* 10 */ "mmmmaaammmm" + /* 8 */ "mmmm...mmmm" + /* 9 */ "mmmmd.dmmmm" + /* 10 */ "mmmm.c.mmmm" + /* 11 */ "mmmmaaammmm" // Level 9 /* z\x* 1 */ @@ -1636,10 +1645,11 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 4 */ "mmmmmmmmmmm" /* 5 */ "mmmmmmmmmmm" /* 6 */ "mmmmmmmmmmm" - /* 7 */ "mmmm...mmmm" - /* 8 */ "mmmmc.cmmmm" - /* 9 */ "mmmm...mmmm" - /* 10 */ "mmmm.d.mmmm" + /* 7 */ "mmmmmmmmmmm" + /* 8 */ "mmmm...mmmm" + /* 9 */ "mmmmd.dmmmm" + /* 10 */ "mmmm...mmmm" + /* 11 */ "mmmm.b.mmmm" // Level 10 /* z\x* 1 */ @@ -1652,9 +1662,10 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 5 */ "mmmmmmmmmmm" /* 6 */ "mmmmmmmmmmm" /* 7 */ "mmmmmmmmmmm" - /* 8 */ "mmmmc.cmmmm" - /* 9 */ "mmmm...mmmm" + /* 8 */ "mmmmmmmmmmm" + /* 9 */ "mmmmd.dmmmm" /* 10 */ "mmmm...mmmm" + /* 11 */ "mmmm...mmmm" // Level 11 /* z\x* 1 */ @@ -1667,19 +1678,20 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = /* 5 */ "mmmmmmmmmmm" /* 6 */ "mmmmmmmmmmm" /* 7 */ "mmmmmmmmmmm" - /* 8 */ "mmmmaaammmm" - /* 9 */ "mmmm.f.mmmm" - /* 10 */ "mmmm...mmmm", + /* 8 */ "mmmmmmmmmmm" + /* 9 */ "mmmmaaammmm" + /* 10 */ "mmmm.f.mmmm" + /* 11 */ "mmmm...mmmm", // Connectors: - "3: 0, 5, 5: 4\n" /* Type 3, direction X- */ - "-3: 0, 5, 5: 4\n" /* Type -3, direction X- */ - "3: 10, 5, 5: 5\n" /* Type 3, direction X+ */ - "-3: 10, 5, 5: 5\n" /* Type -3, direction X+ */ - "3: 5, 9, 10: 3\n" /* Type 3, direction Z+ */ - "-3: 5, 9, 10: 3\n" /* Type -3, direction Z+ */ - "3: 5, 1, 0: 2\n" /* Type 3, direction Z- */ - "-3: 5, 1, 0: 2\n" /* Type -3, direction Z- */, + "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 */ @@ -3143,17 +3155,17 @@ const cPrefab::sDef g_PlainsVillagePrefabs[] = // Level 0 /* z\x* */ /* * 0123456789 */ - /* 0 */ "mmmmmmmmmm" - /* 1 */ "maaaaammmm" - /* 2 */ "maaaaammmm" - /* 3 */ "maaaaabbbb" + /* 0 */ ".........." + /* 1 */ ".aaaaa...." + /* 2 */ ".aaaaa...." + /* 3 */ ".aaaaabbbb" /* 4 */ "aaaaaabbbb" /* 5 */ "aaaaaabbbb" /* 6 */ "aaaaaabbbb" - /* 7 */ "maaaaabbbb" - /* 8 */ "maaaaabbbb" - /* 9 */ "maaaaammmm" - /* 10 */ "mmmmmmmmmm" + /* 7 */ ".aaaaabbbb" + /* 8 */ ".aaaaabbbb" + /* 9 */ ".aaaaa...." + /* 10 */ ".........." // Level 1 /* z\x* */ From 0b7ed0f4934b75f959d13ce7b8a4c73cb88ce318 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 31 May 2014 11:47:03 +0200 Subject: [PATCH 197/312] Add doxy-comment --- src/Blocks/BlockDoor.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index c1e4de9d4..d8ce916fa 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -137,12 +137,13 @@ public: static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { - NIBBLETYPE Meta = GetMetaFromRightDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); return ((Meta & 0x4) != 0); } - static NIBBLETYPE GetMetaFromRightDoor(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) + /** Read the meta from the true part of the door and returns a meta with all infos include. */ + static NIBBLETYPE GetTrueDoorMeta(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); @@ -162,7 +163,7 @@ public: 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); - NIBBLETYPE Meta = GetMetaFromRightDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); if (!IsDoor(Block)) { From 683da71c0fa33c2542e28bed5d2f106ddfc68b64 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sat, 31 May 2014 11:48:54 +0200 Subject: [PATCH 198/312] Moved the IsDoor check before the meta get. --- src/Blocks/BlockDoor.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index d8ce916fa..eaa039c50 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -163,13 +163,12 @@ public: 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); - NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - if (!IsDoor(Block)) { return; } + NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); bool Opened = (Meta & 0x4) != 0; if (Opened == a_Open) { From d1b23060ada3946d68453e381867861bc768999b Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sat, 31 May 2014 14:14:55 +0200 Subject: [PATCH 199/312] Used recommendations --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 4 ++-- src/Bindings/PluginManager.h | 2 +- src/Entities/ProjectileEntity.cpp | 3 +-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index a6f91382c..3f1e0f0bc 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, eBlockFace a_Face, const Vector3i * a_BlockHitPos) = 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 97f78351b..da98f3f95 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,14 +1108,14 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a -bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face, const Vector3i * a_BlockHitPos) +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, a_Face, a_BlockHitPos, 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 627aa3cc8..6d0a90654 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, eBlockFace a_Face, const Vector3i * a_BlockHitPos) 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 a5c904a77..066616c2a 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,7 +1154,7 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti -bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile, eBlockFace a_Face, const Vector3i * a_BlockHitPos) +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()) @@ -1163,7 +1163,7 @@ bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile } for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnProjectileHitBlock(a_Projectile, a_Face, a_BlockHitPos)) + if ((*itr)->OnProjectileHitBlock(a_Projectile, a_BlockX, a_BlockY, a_BlockZ, a_Face, a_BlockHitPos)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 35755459a..47aab74e6 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, eBlockFace a_Face, const Vector3i * a_BlockHitPos); + 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/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp index 7a869a957..acb10539d 100644 --- a/src/Entities/ProjectileEntity.cpp +++ b/src/Entities/ProjectileEntity.cpp @@ -68,8 +68,7 @@ protected: if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face)) { Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff; - const Vector3i BlockHitPos = Vector3i(Intersection); - if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, Face, &BlockHitPos)) + if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, a_BlockX, a_BlockY, a_BlockZ, Face, &Intersection)) { return false; } From b436359237a9faa1dc5709e4359b73aa6faf4f78 Mon Sep 17 00:00:00 2001 From: JoannisO Date: Sat, 31 May 2014 16:08:15 +0200 Subject: [PATCH 200/312] - Changed the name of the ProjectileLookVector method. Note: I still think the new name is unclear. Any other suggestions are welcome. --- src/BlockEntities/DispenserEntity.cpp | 4 ++-- src/BlockEntities/DispenserEntity.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 799d41a1e..db1b405cd 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -198,7 +198,7 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) void cDispenserEntity::SpawnProjectileFromDispenser(cChunk & a_Chunk, int & a_DispX, int & a_DispY, int & a_DispZ, cProjectileEntity::eKind a_kind) { - Vector3d Angle = GetProjectileLookVector(a_Chunk); + Vector3d Angle = GetShootVector(a_Chunk); cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(a_DispX, a_DispZ); double EntityX = 0.5 + (a_DispX + DispChunk->GetPosX() * cChunkDef::Width); @@ -209,7 +209,7 @@ void cDispenserEntity::SpawnProjectileFromDispenser(cChunk & a_Chunk, int & a_Di -Vector3d cDispenserEntity::GetProjectileLookVector(cChunk & a_Chunk) +Vector3d cDispenserEntity::GetShootVector(cChunk & a_Chunk) { NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); int Direction = 0; diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index 76aaccd3c..adbe2070c 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -33,7 +33,7 @@ private: void SpawnProjectileFromDispenser(cChunk & a_Chunk, int & a_DispX, int & a_DispY, int & a_DispZ, cProjectileEntity::eKind a_kind); // Returns how to aim the projectile - Vector3d GetProjectileLookVector(cChunk & a_Chunk); + Vector3d GetShootVector(cChunk & a_Chunk); /// If the a_BlockInFront is liquidable and the empty bucket can fit, does the m_Contents processing and returns true bool EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum); From 7672ca7eefc7233b507938d0592d1f565191d0ee Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 31 May 2014 22:06:14 +0200 Subject: [PATCH 201/312] Added an initial version of the underwater base generator. --- src/Generating/ComposableGenerator.cpp | 8 + .../Prefabs/UnderwaterBasePrefabs.cpp | 1888 +++++++++++++++++ .../Prefabs/UnderwaterBasePrefabs.h | 15 + src/Generating/UnderwaterBaseGen.cpp | 142 ++ src/Generating/UnderwaterBaseGen.h | 50 + 5 files changed, 2103 insertions(+) create mode 100644 src/Generating/Prefabs/UnderwaterBasePrefabs.cpp create mode 100644 src/Generating/Prefabs/UnderwaterBasePrefabs.h create mode 100644 src/Generating/UnderwaterBaseGen.cpp create mode 100644 src/Generating/UnderwaterBaseGen.h diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 4dd626ed4..cf736ce64 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -25,6 +25,7 @@ #include "Noise3DGenerator.h" #include "POCPieceGenerator.h" #include "Ravines.h" +#include "UnderwaterBaseGen.h" #include "VillageGen.h" @@ -406,6 +407,13 @@ 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 MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); + int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); + m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxDepth, MaxSize, *m_BiomeGen)); + } else if (NoCaseCompare(*itr, "Villages") == 0) { int GridSize = a_IniFile.GetValueSetI("Generator", "VillageGridSize", 384); diff --git a/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp new file mode 100644 index 000000000..54d1b6745 --- /dev/null +++ b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp @@ -0,0 +1,1888 @@ + +// 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[] = +{ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // 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....h" + /* 2 */ "h....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: + 100, + + // 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: 2\n" /* redstonetorchon */ + "m: 19: 0\n" /* sponge */, + + // 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 */ "abb.....bm" + /* 4 */ "mmmbb....b" + /* 5 */ "mmmmmb..kb" + /* 6 */ "mmmmmb...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: 3\n" /* redstonetorchon */ + "o: 76: 4\n" /* redstonetorchon */ + "p: 64: 9\n" /* wooddoorblock */ + "q: 76: 2\n" /* redstonetorchon */, + + // 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 */ "mmmmmmb..bmmmmmm" + /* 5 */ "mmmmmmbl.bmmmmmm" + /* 6 */ "abkkbbb..bbbkkba" + /* 7 */ "j.........n....i" + /* 8 */ "i....o.........p" + /* 9 */ "abkkbbb..bbbkkba" + /* 10 */ "mmmmmmb.qbmmmmmm" + /* 11 */ "mmmmmmb..bmmmmmm" + /* 12 */ "mmmmmmk..kmmmmmm" + /* 13 */ "mmmmmmk..kmmmmmm" + /* 14 */ "mmmmmmb..bmmmmmm" + /* 15 */ "mmmmmmapiammmmmm" + + // 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: 64: 8\n" /* wooddoorblock */ + "h: 76: 4\n" /* redstonetorchon */ + "i: 64: 0\n" /* wooddoorblock */ + "j: 64: 7\n" /* wooddoorblock */ + "k: 76: 3\n" /* redstonetorchon */ + "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......dbbmmmmmm" + /* 2 */ "g...h..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.......i" + /* 2 */ "mmmmmmmb.......j" + /* 3 */ "mmmmmmmbbbbbbbba" + + // Level 7 + /* z\x* 111111 */ + /* * 0123456789012345 */ + /* 0 */ "mmmmmmmmbbbeebba" + /* 1 */ "mmmmmmmmb.k....g" + /* 2 */ "mmmmmmmmb......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: 3\n" /* redstonetorchon */ + "m: 19: 0\n" /* sponge */ + "n: 76: 4\n" /* redstonetorchon */ + "o: 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 */ "mmmmmmb..bmmmmmm" + /* 5 */ "mmmmmmbk.bmmmmmm" + /* 6 */ "abjjbbb..bbbjjba" + /* 7 */ "i.........l....h" + /* 8 */ "h....n.........o" + /* 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: 64: 0\n" /* wooddoorblock */ + "e: 64: 1\n" /* wooddoorblock */ + "f: 64: 8\n" /* wooddoorblock */ + "g: 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 */ "mmmaa..aammmmm" + /* 2 */ "mmaa....aammmm" + /* 3 */ "maa......aammm" + /* 4 */ "ma........aaac" + /* 5 */ "a............d" + /* 6 */ "a............d" + /* 7 */ "ma........aaac" + /* 8 */ "maa......aammm" + /* 9 */ "mmaa....aammmm" + /* 10 */ "mmmaa..aammmmm" + /* 11 */ "mmmma..ammmmmm" + /* 12 */ "mmmma..ammmmmm" + /* 13 */ "mmmmceecmmmmmm" + + // 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 */ "mmmmb..bmmmmmm" + /* 12 */ "mmmma..ammmmmm" + /* 13 */ "mmmmcgfcmmmmmm" + + // 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 */ "mmmbb...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.bbmmmmmm" + /* 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: 1\n" /* wooddoorblock */ + "e: 64: 0\n" /* wooddoorblock */ + "f: 64: 6\n" /* wooddoorblock */ + "g: 76: 3\n" /* redstonetorchon */ + "h: 64: 8\n" /* wooddoorblock */ + "i: 64:12\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..............h" + /* 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: 64: 1\n" /* wooddoorblock */ + "f: 64: 8\n" /* wooddoorblock */ + "g: 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 */ "mmmbb..bbmmm" + /* 4 */ "mmbb....bbmm" + /* 5 */ "mbb......bbm" + /* 6 */ "mb........bm" + /* 7 */ "b..........b" + /* 8 */ "b..........b" + /* 9 */ "mb........bm" + /* 10 */ "mbb......bbm" + /* 11 */ "mmbb....bbmm" + /* 12 */ "mmmbb..bbmmm" + /* 13 */ "mmmmb..bmmmm" + /* 14 */ "mmmmb..bmmmm" + /* 15 */ "mmmmaeeammmm" + + // Level 2 + /* z\x* 11 */ + /* * 012345678901 */ + /* 0 */ "mmmmaffammmm" + /* 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 */ "mmmmagfammmm" + + // 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 */ "mmmcc...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.ccmmmm" + /* 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: 64: 2\n" /* wooddoorblock */ + "f: 64: 0\n" /* wooddoorblock */ + "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* 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 */ "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 */ "mmmmmmc..cmmmmmm" + /* 3 */ "mmmmmcc..ccmmmmm" + /* 4 */ "mmmmcc....ccmmmm" + /* 5 */ "mmmcc......ccmmm" + /* 6 */ "abcc........ccba" + /* 7 */ "i..............h" + /* 8 */ "h..............i" + /* 9 */ "abcc........ccba" + /* 10 */ "mmmcc......ccmmm" + /* 11 */ "mmmmcc....ccmmmm" + /* 12 */ "mmmmmcc..ccmmmmm" + /* 13 */ "mmmmmmc..cmmmmmm" + /* 14 */ "mmmmmmb..bmmmmmm" + /* 15 */ "mmmmmmaihammmmmm" + + // 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 */ "mmmmmcc...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.ccmmmmmm" + /* 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: + 100, + + // 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: 64: 0\n" /* wooddoorblock */ + "e: 64: 8\n" /* wooddoorblock */ + "f: 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 */ "mmmaa..aammmmm" + /* 2 */ "mmaa....aammmm" + /* 3 */ "maa......aammm" + /* 4 */ "ma........aaac" + /* 5 */ "a............d" + /* 6 */ "a............d" + /* 7 */ "ma........aaac" + /* 8 */ "maa......aammm" + /* 9 */ "mmaa....aammmm" + /* 10 */ "mmmaa..aammmmm" + /* 11 */ "mmmmmaammmmmmm" + + // Level 2 + /* z\x* 1111 */ + /* * 01234567890123 */ + /* 0 */ "mmmmmbbmmmmmmm" + /* 1 */ "mmmbb..bbmmmmm" + /* 2 */ "mmbb....bbmmmm" + /* 3 */ "mbb......bbmmm" + /* 4 */ "mb........bbac" + /* 5 */ "b............e" + /* 6 */ "b............f" + /* 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 */ "mmmbb...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.bbmmmmmm" + /* 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: + 100, + + // 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: 64: 0\n" /* wooddoorblock */ + "g: 64: 1\n" /* wooddoorblock */ + "h: 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 */ "mmmbb..bbmmmmm" + /* 4 */ "mmbb....bbmmmm" + /* 5 */ "mbb......bbmmm" + /* 6 */ "mb........bbba" + /* 7 */ "b............f" + /* 8 */ "b............f" + /* 9 */ "mb........bbba" + /* 10 */ "mbb......bbmmm" + /* 11 */ "mmbb....bbmmmm" + /* 12 */ "mmmbb..bbmmmmm" + /* 13 */ "mmmmb..bmmmmmm" + /* 14 */ "mmmmb..bmmmmmm" + /* 15 */ "mmmmaggammmmmm" + /* 16 */ "dddddddddddddd" + + // Level 2 + /* z\x* 1111 */ + /* * 01234567890123 */ + /* 0 */ "mmmmahhammmmmm" + /* 1 */ "mmmmb..bmmmmmm" + /* 2 */ "mmmmc..cmmmmmm" + /* 3 */ "mmmcc..ccmmmmm" + /* 4 */ "mmcc....ccmmmm" + /* 5 */ "mcc......ccmmm" + /* 6 */ "mc........ccba" + /* 7 */ "c............h" + /* 8 */ "c............h" + /* 9 */ "mc........ccba" + /* 10 */ "mcc......ccmmm" + /* 11 */ "mmcc....ccmmmm" + /* 12 */ "mmmcc..ccmmmmm" + /* 13 */ "mmmmc..cmmmmmm" + /* 14 */ "mmmmb..bmmmmmm" + /* 15 */ "mmmmahhammmmmm" + /* 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 */ "mmmcc...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.ccmmmmmm" + /* 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: + 100, + + // DepthWeight: + "", + + // AddWeightIfSame: + 0, + + // MoveToGround: + false, + }, // ViewingTee +}; // 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 */ "h..............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/UnderwaterBaseGen.cpp b/src/Generating/UnderwaterBaseGen.cpp new file mode 100644 index 000000000..ff6f17dde --- /dev/null +++ b/src/Generating/UnderwaterBaseGen.cpp @@ -0,0 +1,142 @@ + +// 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_OriginX, int a_OriginZ, + int a_MaxDepth, + int a_MaxSize + ) : + super(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_MaxDepth, int a_MaxSize, cBiomeGen & a_BiomeGen) : + super(a_Seed, a_GridSize, a_GridSize, 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_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_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..0aefbb4c7 --- /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_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_OriginX, int a_OriginZ) override; +} ; + + + + From 5368e664864094c51a919dc8846f2b41039417e6 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 1 Jun 2014 00:29:17 +0200 Subject: [PATCH 202/312] Missing return; --- src/UI/SlotArea.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index b3e126247..bc8dd9cd6 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1400,6 +1400,7 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick)) { ShiftClicked(a_Player, a_SlotNum, a_ClickedItem); + return; } cItem Slot(*GetSlot(a_SlotNum, a_Player)); From a18b6c231102c78604b9ada7e6ce8a4eb074591e Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 1 Jun 2014 00:43:09 +0200 Subject: [PATCH 203/312] Add HandleSmeltItem() call for achievements. --- src/UI/SlotArea.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index bc8dd9cd6..ac85322b3 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1397,12 +1397,6 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a return; } - if ((a_ClickAction == caShiftLeftClick) || (a_ClickAction == caShiftRightClick)) - { - ShiftClicked(a_Player, a_SlotNum, a_ClickedItem); - return; - } - cItem Slot(*GetSlot(a_SlotNum, a_Player)); if (!Slot.IsSameType(a_ClickedItem)) { @@ -1411,8 +1405,15 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a LOGWARNING("Their item: %s", ItemToFullString(a_ClickedItem).c_str()); bAsync = true; } - cItem & DraggingItem = a_Player.GetDraggingItem(); + 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) @@ -1429,6 +1430,7 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a } DraggingItem.m_ItemCount += Slot.m_ItemCount; + HandleSmeltItem(Slot, a_Player); Slot.Empty(); } else @@ -1443,6 +1445,7 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a case caLeftClick: { DraggingItem = Slot; + HandleSmeltItem(Slot, a_Player); Slot.Empty(); break; } @@ -1456,6 +1459,7 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a { Slot.Empty(); } + HandleSmeltItem(DraggingItem, a_Player); break; } default: From 12f3c0fcdf6e45cbeed630730edb1223a2ecc4d8 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 1 Jun 2014 00:50:35 +0200 Subject: [PATCH 204/312] Players can't set items in the result slot, when they shift a item. --- src/UI/SlotArea.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/UI/SlotArea.h | 1 + 2 files changed, 39 insertions(+) diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index ac85322b3..59a6384b1 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -1484,6 +1484,44 @@ void cSlotAreaFurnace::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a +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 +} + + + + + const cItem * cSlotAreaFurnace::GetSlot(int a_SlotNum, cPlayer & a_Player) const { UNUSED(a_Player); 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; From 75fe89b8aef77d8e684a30aae07c09297d1653cb Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Jun 2014 09:27:27 +0200 Subject: [PATCH 205/312] Updated AlchemistVillage prefabs. --- .../Prefabs/AlchemistVillagePrefabs.cpp | 208 +++++++++--------- 1 file changed, 105 insertions(+), 103 deletions(-) diff --git a/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp index 6e3f82212..eb0d30fdf 100644 --- a/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp +++ b/src/Generating/Prefabs/AlchemistVillagePrefabs.cpp @@ -23,8 +23,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 11, 12, 10, // SizeX = 11, SizeY = 12, SizeZ = 10 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 11, 9, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 11, 10, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -270,8 +270,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 11, 8, 10, // SizeX = 11, SizeY = 8, SizeZ = 10 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 7, 9, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 7, 10, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -455,8 +455,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 11, 5, 13, // SizeX = 11, SizeY = 5, SizeZ = 13 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 4, 12, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 4, 13, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -606,26 +606,28 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 15, 13, 11, // SizeX = 15, SizeY = 13, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 14, 12, 10, // MaxX, MaxY, MaxZ + -1, 0, -1, // MinX, MinY, MinZ + 14, 12, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ - "A:128: 7\n" /* sandstonestairs */ - "B: 44: 1\n" /* step */ - "C:128: 2\n" /* sandstonestairs */ - "D:128: 0\n" /* sandstonestairs */ - "E: 87: 0\n" /* netherstone */ - "F:128: 3\n" /* sandstonestairs */ - "G: 51: 0\n" /* fire */ - "H: 44: 9\n" /* step */ + "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: 2\n" /* wooddoorblock */ + "g: 64: 6\n" /* wooddoorblock */ "h: 64: 0\n" /* wooddoorblock */ "i: 61: 2\n" /* furnace */ "j:118: 0\n" /* cauldronblock */ @@ -633,18 +635,18 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "l: 65: 2\n" /* ladder */ "m: 19: 0\n" /* sponge */ "n:101: 0\n" /* ironbars */ - "o:140: 0\n" /* flowerpotblock */ - "p: 64: 8\n" /* wooddoorblock */ - "q: 50: 3\n" /* torch */ - "r: 69:12\n" /* lever */ - "s: 50: 4\n" /* torch */ - "t:128: 6\n" /* sandstonestairs */ - "u: 44:10\n" /* step */ - "v:128: 1\n" /* sandstonestairs */ - "w: 47: 0\n" /* bookshelf */ - "x: 96:12\n" /* trapdoor */ - "y:128: 4\n" /* sandstonestairs */ - "z:128: 5\n" /* sandstonestairs */, + "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 @@ -681,12 +683,12 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* z\x* 11111 */ /* * 012345678901234 */ /* 0 */ "....cddnnnddc.." - /* 1 */ "....d......od.c" - /* 2 */ "....p.......d.q" - /* 3 */ "....d.......p.." - /* 4 */ "....d.r...l.d.s" + /* 1 */ "....do.....pd.c" + /* 2 */ "....q.......d.r" + /* 3 */ "....d.......s.." + /* 4 */ "....d.t...l.d.u" /* 5 */ "....dddd.dddd.c" - /* 6 */ "....n.......n.." + /* 6 */ "....n..r.r..n.." /* 7 */ "mmmmn.......n.." /* 8 */ "mmmmn.......n.." /* 9 */ "mmmmd.......d.." @@ -695,32 +697,32 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = // Level 3 /* z\x* 11111 */ /* * 012345678901234 */ - /* 0 */ "....cddtttddc.." - /* 1 */ "....duuuuuuuddv" - /* 2 */ "....duuuuuuud.." - /* 3 */ "....duuuuuuud.." - /* 4 */ "....dwwwuuxud.." - /* 5 */ "....ddddddddddv" - /* 6 */ "....yuuuuuuuz.." - /* 7 */ "mmmmyuuuuuuuz.." - /* 8 */ "mmmmyuuuuuuuz.." - /* 9 */ "mmmmduuuuuuud.." - /* 10 */ "mmmmcddAAAddc.." + /* 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 */ "....dBBBdBBBd.." - /* 1 */ "....BcdddddcB.." - /* 2 */ "....Bd.....dB.." - /* 3 */ "....Bd.....dB.." - /* 4 */ "....Bd.....dB.." + /* 0 */ "....dDDDdDDDd.." + /* 1 */ "....DcdddddcD.." + /* 2 */ "....Dd.....dD.." + /* 3 */ "....Dd.....dD.." + /* 4 */ "....Dd.....dD.." /* 5 */ "....dcdd.ddcd.." - /* 6 */ "....B.......B.." - /* 7 */ "mmmmB.......B.." - /* 8 */ "mmmmB.......B.." - /* 9 */ "mmmmB.......B.." - /* 10 */ "mmmmdBBBdBBBd.." + /* 6 */ "....D.......D.." + /* 7 */ "mmmmD.......D.." + /* 8 */ "mmmmD.......D.." + /* 9 */ "mmmmD.......D.." + /* 10 */ "mmmmdDDDdDDDd.." // Level 5 /* z\x* 11111 */ @@ -741,10 +743,10 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* z\x* 11111 */ /* * 012345678901234 */ /* 0 */ "..............." - /* 1 */ ".....cddtddc..." - /* 2 */ ".....yuuuuuz..." - /* 3 */ ".....yuuuuuz..." - /* 4 */ ".....yuuuuuz..." + /* 1 */ ".....cddvddc..." + /* 2 */ ".....AwwwwwB..." + /* 3 */ ".....AwwwwwB..." + /* 4 */ ".....AwwwwwB..." /* 5 */ ".....cdddddc..." /* 6 */ "..............." /* 7 */ "..............." @@ -756,11 +758,11 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* z\x* 11111 */ /* * 012345678901234 */ /* 0 */ "..............." - /* 1 */ ".....dBBdBBd..." - /* 2 */ ".....B.ddd.B..." + /* 1 */ ".....dDDdDDd..." + /* 2 */ ".....D.ddd.D..." /* 3 */ ".....d.ddd.d..." - /* 4 */ ".....B.ddd.B..." - /* 5 */ ".....dBBdBBd..." + /* 4 */ ".....D.ddd.D..." + /* 5 */ ".....dDDdDDd..." /* 6 */ "..............." /* 7 */ "..............." /* 8 */ "..............." @@ -772,9 +774,9 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* * 012345678901234 */ /* 0 */ "..............." /* 1 */ "..............." - /* 2 */ ".......cCc....." - /* 3 */ ".......DEv....." - /* 4 */ ".......cFc....." + /* 2 */ ".......cEc....." + /* 3 */ ".......FGx....." + /* 4 */ ".......cHc....." /* 5 */ "..............." /* 6 */ "..............." /* 7 */ "..............." @@ -788,7 +790,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..............." /* 1 */ "..............." /* 2 */ ".......c.c....." - /* 3 */ "........G......" + /* 3 */ "........I......" /* 4 */ ".......c.c....." /* 5 */ "..............." /* 6 */ "..............." @@ -802,9 +804,9 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* * 012345678901234 */ /* 0 */ "..............." /* 1 */ "..............." - /* 2 */ ".......ctc....." - /* 3 */ ".......y.z....." - /* 4 */ ".......cAc....." + /* 2 */ ".......cvc....." + /* 3 */ ".......A.B....." + /* 4 */ ".......cCc....." /* 5 */ "..............." /* 6 */ "..............." /* 7 */ "..............." @@ -818,7 +820,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* 0 */ "..............." /* 1 */ "..............." /* 2 */ ".......ddd....." - /* 3 */ ".......dHd....." + /* 3 */ ".......dJd....." /* 4 */ ".......ddd....." /* 5 */ "..............." /* 6 */ "..............." @@ -832,9 +834,9 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = /* * 012345678901234 */ /* 0 */ "..............." /* 1 */ "..............." - /* 2 */ ".......B.B....." + /* 2 */ ".......D.D....." /* 3 */ "..............." - /* 4 */ ".......B.B....." + /* 4 */ ".......D.D....." /* 5 */ "..............." /* 6 */ "..............." /* 7 */ "..............." @@ -877,8 +879,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 7, 11, 7, // SizeX = 7, SizeY = 11, SizeZ = 7 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 6, 10, 6, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 7, 10, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1050,8 +1052,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 5, 5, 7, // SizeX = 5, SizeY = 5, SizeZ = 7 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 4, 4, 6, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 5, 4, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1160,8 +1162,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 7, 5, 11, // SizeX = 7, SizeY = 5, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 6, 4, 10, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 7, 4, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1291,8 +1293,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 9, 5, 7, // SizeX = 9, SizeY = 5, SizeZ = 7 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 8, 4, 6, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 9, 4, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1400,8 +1402,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 5, 5, 11, // SizeX = 5, SizeY = 5, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 4, 4, 10, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 5, 4, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1428,7 +1430,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "u:128: 5\n" /* sandstonestairs */ "v:128: 7\n" /* sandstonestairs */ "w: 44: 1\n" /* step */ - "x: 96: 7\n" /* trapdoor */, + "x: 96: 1\n" /* trapdoor */, // Block data: // Level 0 @@ -1536,8 +1538,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 9, 5, 9, // SizeX = 9, SizeY = 5, SizeZ = 9 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 8, 4, 8, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 9, 4, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1657,8 +1659,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 9, 5, 9, // SizeX = 9, SizeY = 5, SizeZ = 9 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 8, 4, 8, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 9, 4, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1783,8 +1785,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 9, 5, 11, // SizeX = 9, SizeY = 5, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 8, 4, 10, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 9, 4, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -1914,8 +1916,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 5, 8, 7, // SizeX = 5, SizeY = 8, SizeZ = 7 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 4, 7, 6, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 5, 7, 7, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -2054,8 +2056,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 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 + -1, 0, 0, // MinX, MinY, MinZ + 15, 7, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -2219,8 +2221,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 11, 9, 9, // SizeX = 11, SizeY = 9, SizeZ = 9 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 10, 8, 8, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 11, 8, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -2413,8 +2415,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 12, 10, 11, // SizeX = 12, SizeY = 10, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 11, 9, 10, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 12, 9, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -2441,7 +2443,7 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = "u:128: 5\n" /* sandstonestairs */ "v:128: 7\n" /* sandstonestairs */ "w: 44: 1\n" /* step */ - "x: 96: 6\n" /* trapdoor */ + "x: 96: 4\n" /* trapdoor */ "y:126: 0\n" /* woodenslab */ "z:128: 4\n" /* sandstonestairs */, @@ -2631,8 +2633,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 9, 5, 11, // SizeX = 9, SizeY = 5, SizeZ = 11 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 8, 4, 10, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 9, 4, 11, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ @@ -2762,8 +2764,8 @@ const cPrefab::sDef g_AlchemistVillagePrefabs[] = 13, 9, 9, // SizeX = 13, SizeY = 9, SizeZ = 9 // Hitbox (relative to bounding box): - 0, 0, 0, // MinX, MinY, MinZ - 12, 8, 8, // MaxX, MaxY, MaxZ + -1, 0, 0, // MinX, MinY, MinZ + 13, 8, 9, // MaxX, MaxY, MaxZ // Block definitions: ".: 0: 0\n" /* air */ From 046c1497979cf96a2fc4d1847dad2d7daf050e60 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Jun 2014 10:07:57 +0200 Subject: [PATCH 206/312] Updated UnderwaterBase prefabs. --- .../Prefabs/UnderwaterBasePrefabs.cpp | 226 ++++++++++-------- 1 file changed, 123 insertions(+), 103 deletions(-) diff --git a/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp index 54d1b6745..a20ff9e26 100644 --- a/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp +++ b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp @@ -60,8 +60,8 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* z\x* 111111 */ /* * 0123456789012345 */ /* 0 */ "abeebbbeebbbeeba" - /* 1 */ "f.........g....h" - /* 2 */ "h....i.........f" + /* 1 */ "f...g......g...h" + /* 2 */ "h...i......i...f" /* 3 */ "abeebbbeebbbeeba" // Level 3 @@ -88,7 +88,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = true, // DefaultWeight: - 100, + 2000, // DepthWeight: "", @@ -125,8 +125,10 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "h: 64:12\n" /* wooddoorblock */ "i: 76: 3\n" /* redstonetorchon */ "j: 64: 8\n" /* wooddoorblock */ - "k: 76: 2\n" /* redstonetorchon */ - "m: 19: 0\n" /* sponge */, + "k: 76: 4\n" /* redstonetorchon */ + "l: 76: 2\n" /* redstonetorchon */ + "m: 19: 0\n" /* sponge */ + "n: 76: 1\n" /* redstonetorchon */, // Block data: // Level 0 @@ -163,10 +165,10 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 0 */ "abggbbmmmm" /* 1 */ "h...i.bbmm" /* 2 */ "j.......bm" - /* 3 */ "abb.....bm" + /* 3 */ "abbk....bm" /* 4 */ "mmmbb....b" - /* 5 */ "mmmmmb..kb" - /* 6 */ "mmmmmb...g" + /* 5 */ "mmmmmb..lb" + /* 6 */ "mmmmmbn..g" /* 7 */ "mmmmmmb..g" /* 8 */ "mmmmmmb..b" /* 9 */ "mmmmmmahja" @@ -241,10 +243,10 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "k: 20: 0\n" /* glass */ "l: 76: 1\n" /* redstonetorchon */ "m: 19: 0\n" /* sponge */ - "n: 76: 3\n" /* redstonetorchon */ - "o: 76: 4\n" /* redstonetorchon */ - "p: 64: 9\n" /* wooddoorblock */ - "q: 76: 2\n" /* redstonetorchon */, + "n: 76: 2\n" /* redstonetorchon */ + "o: 76: 3\n" /* redstonetorchon */ + "p: 76: 4\n" /* redstonetorchon */ + "q: 64: 9\n" /* wooddoorblock */, // Block data: // Level 0 @@ -294,18 +296,18 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 1 */ "mmmmmmb..bmmmmmm" /* 2 */ "mmmmmmk..kmmmmmm" /* 3 */ "mmmmmmk..kmmmmmm" - /* 4 */ "mmmmmmb..bmmmmmm" - /* 5 */ "mmmmmmbl.bmmmmmm" + /* 4 */ "mmmmmmblnbmmmmmm" + /* 5 */ "mmmmmmb..bmmmmmm" /* 6 */ "abkkbbb..bbbkkba" - /* 7 */ "j.........n....i" - /* 8 */ "i....o.........p" + /* 7 */ "j...o......o...i" + /* 8 */ "i...p......p...q" /* 9 */ "abkkbbb..bbbkkba" - /* 10 */ "mmmmmmb.qbmmmmmm" - /* 11 */ "mmmmmmb..bmmmmmm" + /* 10 */ "mmmmmmb..bmmmmmm" + /* 11 */ "mmmmmmblnbmmmmmm" /* 12 */ "mmmmmmk..kmmmmmm" /* 13 */ "mmmmmmk..kmmmmmm" /* 14 */ "mmmmmmb..bmmmmmm" - /* 15 */ "mmmmmmapiammmmmm" + /* 15 */ "mmmmmmaqiammmmmm" // Level 3 /* z\x* 111111 */ @@ -380,11 +382,11 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "d: 53: 0\n" /* woodstairs */ "e: 20: 0\n" /* glass */ "f: 64: 9\n" /* wooddoorblock */ - "g: 64: 8\n" /* wooddoorblock */ - "h: 76: 4\n" /* redstonetorchon */ - "i: 64: 0\n" /* wooddoorblock */ - "j: 64: 7\n" /* wooddoorblock */ - "k: 76: 3\n" /* redstonetorchon */ + "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 */, @@ -409,8 +411,8 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* z\x* 111111 */ /* * 0123456789012345 */ /* 0 */ "abeebbbbbmmmmmmm" - /* 1 */ "f......dbbmmmmmm" - /* 2 */ "g...h..dbbmmmmmm" + /* 1 */ "f...g..dbbmmmmmm" + /* 2 */ "h...i..dbbmmmmmm" /* 3 */ "abeebbbbbmmmmmmm" // Level 3 @@ -441,16 +443,16 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* z\x* 111111 */ /* * 0123456789012345 */ /* 0 */ "mmmmmmmbbbbbbbba" - /* 1 */ "mmmmmmmb.......i" - /* 2 */ "mmmmmmmb.......j" + /* 1 */ "mmmmmmmb.......j" + /* 2 */ "mmmmmmmb.......k" /* 3 */ "mmmmmmmbbbbbbbba" // Level 7 /* z\x* 111111 */ /* * 0123456789012345 */ /* 0 */ "mmmmmmmmbbbeebba" - /* 1 */ "mmmmmmmmb.k....g" - /* 2 */ "mmmmmmmmb......l" + /* 1 */ "mmmmmmmmb.g....h" + /* 2 */ "mmmmmmmmb.i....l" /* 3 */ "mmmmmmmmbbbeebba" // Level 8 @@ -515,10 +517,11 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "i: 64:12\n" /* wooddoorblock */ "j: 20: 0\n" /* glass */ "k: 76: 1\n" /* redstonetorchon */ - "l: 76: 3\n" /* redstonetorchon */ + "l: 76: 2\n" /* redstonetorchon */ "m: 19: 0\n" /* sponge */ - "n: 76: 4\n" /* redstonetorchon */ - "o: 64: 9\n" /* wooddoorblock */, + "n: 76: 3\n" /* redstonetorchon */ + "o: 76: 4\n" /* redstonetorchon */ + "p: 64: 9\n" /* wooddoorblock */, // Block data: // Level 0 @@ -556,11 +559,11 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 1 */ "mmmmmmb..bmmmmmm" /* 2 */ "mmmmmmj..jmmmmmm" /* 3 */ "mmmmmmj..jmmmmmm" - /* 4 */ "mmmmmmb..bmmmmmm" - /* 5 */ "mmmmmmbk.bmmmmmm" + /* 4 */ "mmmmmmbklbmmmmmm" + /* 5 */ "mmmmmmb..bmmmmmm" /* 6 */ "abjjbbb..bbbjjba" - /* 7 */ "i.........l....h" - /* 8 */ "h....n.........o" + /* 7 */ "i...n......n...h" + /* 8 */ "h...o......o...p" /* 9 */ "abjjbbbjjbbbjjba" // Level 3 @@ -625,10 +628,14 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "a: 5: 0\n" /* wood */ "b: 20: 0\n" /* glass */ "c: 5: 5\n" /* wood */ - "d: 64: 0\n" /* wooddoorblock */ - "e: 64: 1\n" /* wooddoorblock */ - "f: 64: 8\n" /* wooddoorblock */ - "g: 64: 9\n" /* wooddoorblock */ + "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: @@ -654,19 +661,19 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* z\x* 1111 */ /* * 01234567890123 */ /* 0 */ "mmmmmaammmmmmm" - /* 1 */ "mmmaa..aammmmm" + /* 1 */ "mmmaaddaammmmm" /* 2 */ "mmaa....aammmm" /* 3 */ "maa......aammm" /* 4 */ "ma........aaac" - /* 5 */ "a............d" - /* 6 */ "a............d" + /* 5 */ "ae........d..f" + /* 6 */ "ae........g..f" /* 7 */ "ma........aaac" /* 8 */ "maa......aammm" /* 9 */ "mmaa....aammmm" - /* 10 */ "mmmaa..aammmmm" + /* 10 */ "mmmaaehaammmmm" /* 11 */ "mmmma..ammmmmm" /* 12 */ "mmmma..ammmmmm" - /* 13 */ "mmmmceecmmmmmm" + /* 13 */ "mmmmciicmmmmmm" // Level 2 /* z\x* 1111 */ @@ -676,15 +683,15 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 2 */ "mmbb....bbmmmm" /* 3 */ "mbb......bbmmm" /* 4 */ "mb........bbac" - /* 5 */ "b............f" - /* 6 */ "b............g" + /* 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 */ "mmmmcgfcmmmmmm" + /* 13 */ "mmmmckjcmmmmmm" // Level 3 /* z\x* 1111 */ @@ -804,12 +811,12 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "a: 5: 0\n" /* wood */ "b: 5: 5\n" /* wood */ "c: 20: 0\n" /* glass */ - "d: 64: 1\n" /* wooddoorblock */ + "d: 64: 5\n" /* wooddoorblock */ "e: 64: 0\n" /* wooddoorblock */ - "f: 64: 6\n" /* wooddoorblock */ + "f: 64: 2\n" /* wooddoorblock */ "g: 76: 3\n" /* redstonetorchon */ - "h: 64: 8\n" /* wooddoorblock */ - "i: 64:12\n" /* wooddoorblock */ + "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 */, @@ -840,7 +847,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* * 0123456789012345 */ /* 0 */ "mmaccccccccccamm" /* 1 */ "bag..........gab" - /* 2 */ "h..............h" + /* 2 */ "h..............i" /* 3 */ "i..............j" /* 4 */ "bak..........kab" /* 5 */ "mmaccccccccccamm" @@ -912,9 +919,11 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "b: 5: 0\n" /* wood */ "c: 20: 0\n" /* glass */ "d: 64: 3\n" /* wooddoorblock */ - "e: 64: 1\n" /* wooddoorblock */ - "f: 64: 8\n" /* wooddoorblock */ - "g: 64: 9\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: @@ -944,24 +953,24 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 0 */ "mmmmaddammmm" /* 1 */ "mmmmb..bmmmm" /* 2 */ "mmmmb..bmmmm" - /* 3 */ "mmmbb..bbmmm" + /* 3 */ "mmmbbefbbmmm" /* 4 */ "mmbb....bbmm" /* 5 */ "mbb......bbm" /* 6 */ "mb........bm" - /* 7 */ "b..........b" - /* 8 */ "b..........b" + /* 7 */ "be........fb" + /* 8 */ "be........fb" /* 9 */ "mb........bm" /* 10 */ "mbb......bbm" /* 11 */ "mmbb....bbmm" - /* 12 */ "mmmbb..bbmmm" + /* 12 */ "mmmbbefbbmmm" /* 13 */ "mmmmb..bmmmm" /* 14 */ "mmmmb..bmmmm" - /* 15 */ "mmmmaeeammmm" + /* 15 */ "mmmmaggammmm" // Level 2 /* z\x* 11 */ /* * 012345678901 */ - /* 0 */ "mmmmaffammmm" + /* 0 */ "mmmmahiammmm" /* 1 */ "mmmmb..bmmmm" /* 2 */ "mmmmc..cmmmm" /* 3 */ "mmmcc..ccmmm" @@ -976,7 +985,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 12 */ "mmmcc..ccmmm" /* 13 */ "mmmmc..cmmmm" /* 14 */ "mmmmb..bmmmm" - /* 15 */ "mmmmagfammmm" + /* 15 */ "mmmmaihammmm" // Level 3 /* z\x* 11 */ @@ -1125,12 +1134,16 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "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 */ - "m: 19: 0\n" /* sponge */, + "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 @@ -1159,39 +1172,39 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 0 */ "mmmmmmaddammmmmm" /* 1 */ "mmmmmmb..bmmmmmm" /* 2 */ "mmmmmmb..bmmmmmm" - /* 3 */ "mmmmmbb..bbmmmmm" + /* 3 */ "mmmmmbbefbbmmmmm" /* 4 */ "mmmmbb....bbmmmm" /* 5 */ "mmmbb......bbmmm" /* 6 */ "abbb........bbba" - /* 7 */ "e..............f" - /* 8 */ "e..............f" + /* 7 */ "g..h........h..i" + /* 8 */ "g..j........j..i" /* 9 */ "abbb........bbba" /* 10 */ "mmmbb......bbmmm" /* 11 */ "mmmmbb....bbmmmm" - /* 12 */ "mmmmmbb..bbmmmmm" + /* 12 */ "mmmmmbbefbbmmmmm" /* 13 */ "mmmmmmb..bmmmmmm" /* 14 */ "mmmmmmb..bmmmmmm" - /* 15 */ "mmmmmmaggammmmmm" + /* 15 */ "mmmmmmakkammmmmm" // Level 2 /* z\x* 111111 */ /* * 0123456789012345 */ - /* 0 */ "mmmmmmahiammmmmm" + /* 0 */ "mmmmmmalnammmmmm" /* 1 */ "mmmmmmb..bmmmmmm" /* 2 */ "mmmmmmc..cmmmmmm" /* 3 */ "mmmmmcc..ccmmmmm" /* 4 */ "mmmmcc....ccmmmm" /* 5 */ "mmmcc......ccmmm" /* 6 */ "abcc........ccba" - /* 7 */ "i..............h" - /* 8 */ "h..............i" + /* 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 */ "mmmmmmaihammmmmm" + /* 15 */ "mmmmmmanlammmmmm" // Level 3 /* z\x* 111111 */ @@ -1293,7 +1306,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = true, // DefaultWeight: - 100, + 50, // DepthWeight: "", @@ -1323,9 +1336,12 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "a: 5: 0\n" /* wood */ "b: 20: 0\n" /* glass */ "c: 5: 5\n" /* wood */ - "d: 64: 0\n" /* wooddoorblock */ - "e: 64: 8\n" /* wooddoorblock */ - "f: 64: 9\n" /* wooddoorblock */ + "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: @@ -1349,16 +1365,16 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* z\x* 1111 */ /* * 01234567890123 */ /* 0 */ "mmmmmaammmmmmm" - /* 1 */ "mmmaa..aammmmm" + /* 1 */ "mmmaaddaammmmm" /* 2 */ "mmaa....aammmm" /* 3 */ "maa......aammm" /* 4 */ "ma........aaac" - /* 5 */ "a............d" - /* 6 */ "a............d" + /* 5 */ "ae........d..f" + /* 6 */ "ae........g..f" /* 7 */ "ma........aaac" /* 8 */ "maa......aammm" /* 9 */ "mmaa....aammmm" - /* 10 */ "mmmaa..aammmmm" + /* 10 */ "mmmaaggaammmmm" /* 11 */ "mmmmmaammmmmmm" // Level 2 @@ -1369,8 +1385,8 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 2 */ "mmbb....bbmmmm" /* 3 */ "mbb......bbmmm" /* 4 */ "mb........bbac" - /* 5 */ "b............e" - /* 6 */ "b............f" + /* 5 */ "b............h" + /* 6 */ "b............i" /* 7 */ "mb........bbac" /* 8 */ "mbb......bbmmm" /* 9 */ "mmbb....bbmmmm" @@ -1455,7 +1471,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = true, // DefaultWeight: - 100, + 200, // DepthWeight: "", @@ -1487,9 +1503,13 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = "c: 20: 0\n" /* glass */ "d: 1: 0\n" /* stone */ "e: 64: 3\n" /* wooddoorblock */ - "f: 64: 0\n" /* wooddoorblock */ - "g: 64: 1\n" /* wooddoorblock */ - "h: 64: 8\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: @@ -1520,40 +1540,40 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 0 */ "mmmmaeeammmmmm" /* 1 */ "mmmmb..bmmmmmm" /* 2 */ "mmmmb..bmmmmmm" - /* 3 */ "mmmbb..bbmmmmm" + /* 3 */ "mmmbbfgbbmmmmm" /* 4 */ "mmbb....bbmmmm" /* 5 */ "mbb......bbmmm" /* 6 */ "mb........bbba" - /* 7 */ "b............f" - /* 8 */ "b............f" + /* 7 */ "bf........h..i" + /* 8 */ "bf........j..i" /* 9 */ "mb........bbba" /* 10 */ "mbb......bbmmm" /* 11 */ "mmbb....bbmmmm" - /* 12 */ "mmmbb..bbmmmmm" + /* 12 */ "mmmbbfgbbmmmmm" /* 13 */ "mmmmb..bmmmmmm" /* 14 */ "mmmmb..bmmmmmm" - /* 15 */ "mmmmaggammmmmm" + /* 15 */ "mmmmakkammmmmm" /* 16 */ "dddddddddddddd" // Level 2 /* z\x* 1111 */ /* * 01234567890123 */ - /* 0 */ "mmmmahhammmmmm" + /* 0 */ "mmmmallammmmmm" /* 1 */ "mmmmb..bmmmmmm" /* 2 */ "mmmmc..cmmmmmm" /* 3 */ "mmmcc..ccmmmmm" /* 4 */ "mmcc....ccmmmm" /* 5 */ "mcc......ccmmm" /* 6 */ "mc........ccba" - /* 7 */ "c............h" - /* 8 */ "c............h" + /* 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 */ "mmmmahhammmmmm" + /* 15 */ "mmmmallammmmmm" /* 16 */ "dddddddddddddd" // Level 3 @@ -1653,7 +1673,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = true, // DefaultWeight: - 100, + 75, // DepthWeight: "", From 319169eafbbe5630a311051ea5fdf91e7f482a71 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Sun, 1 Jun 2014 14:06:47 +0200 Subject: [PATCH 207/312] Made a_BlockHitPos a reference --- src/Bindings/Plugin.h | 2 +- src/Bindings/PluginLua.cpp | 4 ++-- src/Bindings/PluginLua.h | 2 +- src/Bindings/PluginManager.cpp | 2 +- src/Bindings/PluginManager.h | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 3f1e0f0bc..837b1ae13 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, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d * a_BlockHitPos) = 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 da98f3f95..46ee7da9e 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -1108,14 +1108,14 @@ bool cPluginLua::OnPreCrafting(const cPlayer * a_Player, const cCraftingGrid * a -bool cPluginLua::OnProjectileHitBlock(cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d * a_BlockHitPos) +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, a_BlockX, a_BlockY, a_BlockZ, a_Face, a_BlockHitPos, 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 6d0a90654..ec74f07c6 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, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d * a_BlockHitPos) 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 066616c2a..4f528c2ae 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1154,7 +1154,7 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti -bool cPluginManager::CallHookProjectileHitBlock(cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d * a_BlockHitPos) +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()) diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 47aab74e6..6c4e8bae7 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, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d * a_BlockHitPos); + 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); From 869cd7a2080d6072f90016afd7067f871482a5ac Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 1 Jun 2014 15:19:01 +0200 Subject: [PATCH 208/312] Hot-fixed AnvilStats compilation for MSVC2013. --- Tools/AnvilStats/AnvilStats.sln | 45 +++++++++++++++++++++++--------- Tools/AnvilStats/Globals.h | 22 ++++++++++++++++ Tools/AnvilStats/SpringStats.cpp | 2 +- 3 files changed, 56 insertions(+), 13 deletions(-) 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/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; From 476fdc99523c458506416b06d9b939d1e6065364 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 1 Jun 2014 17:05:51 +0100 Subject: [PATCH 209/312] Use abort in SIGSEGV and SIGABRT handlers This should cause Mcserver to generate core dumps when it crashes. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 68eea7f4d..1f458b0c1 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(EXIT_FAILURE); } 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(EXIT_FAILURE); } case SIGINT: case SIGTERM: From 750333855c7d8eeb6993e0bb27a6e505022c8a30 Mon Sep 17 00:00:00 2001 From: worktycho Date: Sun, 1 Jun 2014 17:23:02 +0100 Subject: [PATCH 210/312] abort does not take a parameter. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 1f458b0c1..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"); - abort(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"); - abort(EXIT_FAILURE); + abort(); } case SIGINT: case SIGTERM: From a84f107400a326b0be27c290359220b8bf0e6635 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 1 Jun 2014 20:00:11 +0100 Subject: [PATCH 211/312] Suggestions two --- src/Blocks/BlockPiston.cpp | 6 +++--- src/Chunk.cpp | 16 +++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 1f8e0d9e0..faf639312 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -76,15 +76,15 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta( -int cBlockPistonHandler::FirstPassthroughBlock(int pistonX, int pistonY, int pistonZ, NIBBLETYPE pistonmeta, cWorld * a_World) +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(pistonX, pistonY, pistonZ, pistonmeta, 1); - a_World->GetBlockTypeMeta(pistonX, pistonY, pistonZ, currBlock, 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 diff --git a/src/Chunk.cpp b/src/Chunk.cpp index fbd0a5846..6dce29e68 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1589,13 +1589,15 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT 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 - )) + ( + (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)); From 23b08231086ad1edb373811ae4f93d07a60401ad Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Jun 2014 22:02:58 +0200 Subject: [PATCH 212/312] Update UnderwaterBase prefabs. Added the waterfall room and the decaying sphere room. Re-tweaked the pieces' weights. --- .../Prefabs/UnderwaterBasePrefabs.cpp | 390 +++++++++++++++++- 1 file changed, 378 insertions(+), 12 deletions(-) diff --git a/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp index a20ff9e26..39748a223 100644 --- a/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp +++ b/src/Generating/Prefabs/UnderwaterBasePrefabs.cpp @@ -15,6 +15,169 @@ 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 @@ -88,7 +251,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = true, // DefaultWeight: - 2000, + 500, // DepthWeight: "", @@ -722,7 +885,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 5 */ "mb........bmmm" /* 6 */ "mb........bmmm" /* 7 */ "mmb......bmmmm" - /* 8 */ "mmmbb...bmmmmm" + /* 8 */ "mmmb....bmmmmm" /* 9 */ "mmmmb..bmmmmmm" /* 10 */ "mmmmmbbmmmmmmm" /* 11 */ "mmmmmmmmmmmmmm" @@ -740,7 +903,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 5 */ "mmb......bmmmm" /* 6 */ "mmb......bmmmm" /* 7 */ "mmmb....bmmmmm" - /* 8 */ "mmmmb.bbmmmmmm" + /* 8 */ "mmmmb..bmmmmmm" /* 9 */ "mmmmmbbmmmmmmm" /* 10 */ "mmmmmmmmmmmmmm" /* 11 */ "mmmmmmmmmmmmmm" @@ -1020,7 +1183,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 7 */ "mc........cm" /* 8 */ "mc........cm" /* 9 */ "mmc......cmm" - /* 10 */ "mmmcc...cmmm" + /* 10 */ "mmmc....cmmm" /* 11 */ "mmmmc..cmmmm" /* 12 */ "mmmmmccmmmmm" /* 13 */ "mmmmmmmmmmmm" @@ -1040,7 +1203,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 7 */ "mmc......cmm" /* 8 */ "mmc......cmm" /* 9 */ "mmmc....cmmm" - /* 10 */ "mmmmc.ccmmmm" + /* 10 */ "mmmmc..cmmmm" /* 11 */ "mmmmmccmmmmm" /* 12 */ "mmmmmmmmmmmm" /* 13 */ "mmmmmmmmmmmm" @@ -1239,7 +1402,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 7 */ "mmmc........cmmm" /* 8 */ "mmmc........cmmm" /* 9 */ "mmmmc......cmmmm" - /* 10 */ "mmmmmcc...cmmmmm" + /* 10 */ "mmmmmc....cmmmmm" /* 11 */ "mmmmmmc..cmmmmmm" /* 12 */ "mmmmmmmccmmmmmmm" /* 13 */ "mmmmmmmmmmmmmmmm" @@ -1259,7 +1422,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 7 */ "mmmmc......cmmmm" /* 8 */ "mmmmc......cmmmm" /* 9 */ "mmmmmc....cmmmmm" - /* 10 */ "mmmmmmc.ccmmmmmm" + /* 10 */ "mmmmmmc..cmmmmmm" /* 11 */ "mmmmmmmccmmmmmmm" /* 12 */ "mmmmmmmmmmmmmmmm" /* 13 */ "mmmmmmmmmmmmmmmm" @@ -1420,7 +1583,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 5 */ "mb........bmmm" /* 6 */ "mb........bmmm" /* 7 */ "mmb......bmmmm" - /* 8 */ "mmmbb...bmmmmm" + /* 8 */ "mmmb....bmmmmm" /* 9 */ "mmmmb..bmmmmmm" /* 10 */ "mmmmmbbmmmmmmm" /* 11 */ "mmmmmmmmmmmmmm" @@ -1436,7 +1599,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 5 */ "mmb......bmmmm" /* 6 */ "mmb......bmmmm" /* 7 */ "mmmb....bmmmmm" - /* 8 */ "mmmmb.bbmmmmmm" + /* 8 */ "mmmmb..bmmmmmm" /* 9 */ "mmmmmbbmmmmmmm" /* 10 */ "mmmmmmmmmmmmmm" /* 11 */ "mmmmmmmmmmmmmm" @@ -1610,7 +1773,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 7 */ "mc........cmmm" /* 8 */ "mc........cmmm" /* 9 */ "mmc......cmmmm" - /* 10 */ "mmmcc...cmmmmm" + /* 10 */ "mmmc....cmmmmm" /* 11 */ "mmmmc..cmmmmmm" /* 12 */ "mmmmmccmmmmmmm" /* 13 */ "mmmmmmmmmmmmmm" @@ -1631,7 +1794,7 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = /* 7 */ "mmc......cmmmm" /* 8 */ "mmc......cmmmm" /* 9 */ "mmmc....cmmmmm" - /* 10 */ "mmmmc.ccmmmmmm" + /* 10 */ "mmmmc..cmmmmmm" /* 11 */ "mmmmmccmmmmmmm" /* 12 */ "mmmmmmmmmmmmmm" /* 13 */ "mmmmmmmmmmmmmm" @@ -1684,6 +1847,209 @@ const cPrefab::sDef g_UnderwaterBasePrefabs[] = // 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 @@ -1773,7 +2139,7 @@ const cPrefab::sDef g_UnderwaterBaseStartingPrefabs[] = /* 4 */ "mmmmcc....ccmmmm" /* 5 */ "mmmcc......ccmmm" /* 6 */ "abbc........cbba" - /* 7 */ "h..............h" + /* 7 */ "i..............h" /* 8 */ "h..............i" /* 9 */ "abbc........cbba" /* 10 */ "mmmcc......ccmmm" From 24bea1d0b2b1d0f7400632fd480a24dff84bcad1 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 1 Jun 2014 22:33:53 +0200 Subject: [PATCH 213/312] Generator article now has all biome genertors and most their imgs. --- docs/Generator.html | 164 +++++++++++++++++- docs/img/biomes.jpg | Bin 0 -> 34538 bytes docs/img/distortedvoronoibiomes.png | Bin 0 -> 6012 bytes docs/img/finishers.jpg | Bin 0 -> 40652 bytes docs/img/jittergrid.jpg | Bin 0 -> 51390 bytes docs/img/jittergridlocality.jpg | Bin 0 -> 40758 bytes docs/img/multistepmapbiomes.png | Bin 0 -> 11103 bytes docs/img/perlin.jpg | Bin 0 -> 24105 bytes docs/img/perlinheightmap.jpg | Bin 0 -> 53543 bytes docs/img/temperaturehumiditydecisionhills.jpg | Bin 0 -> 88494 bytes .../img/temperaturehumiditydecisionsimple.jpg | Bin 0 -> 51736 bytes docs/img/terraincomposition.jpg | Bin 0 -> 43271 bytes docs/img/terrainheight.jpg | Bin 0 -> 29098 bytes docs/img/twolevelbiomes.png | Bin 0 -> 33816 bytes docs/img/voronoijitterbiomes.png | Bin 0 -> 4268 bytes 15 files changed, 156 insertions(+), 8 deletions(-) create mode 100644 docs/img/biomes.jpg create mode 100644 docs/img/distortedvoronoibiomes.png create mode 100644 docs/img/finishers.jpg create mode 100644 docs/img/jittergrid.jpg create mode 100644 docs/img/jittergridlocality.jpg create mode 100644 docs/img/multistepmapbiomes.png create mode 100644 docs/img/perlin.jpg create mode 100644 docs/img/perlinheightmap.jpg create mode 100644 docs/img/temperaturehumiditydecisionhills.jpg create mode 100644 docs/img/temperaturehumiditydecisionsimple.jpg create mode 100644 docs/img/terraincomposition.jpg create mode 100644 docs/img/terrainheight.jpg create mode 100644 docs/img/twolevelbiomes.png create mode 100644 docs/img/voronoijitterbiomes.png diff --git a/docs/Generator.html b/docs/Generator.html index f71ce1c71..b7586a183 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -13,6 +13,7 @@ with specific implementation notes regarding MCServer.

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.

+

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, @@ -35,11 +36,14 @@ distinction will be discussed later.

+ +

Reversing the flow

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.

+

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 @@ -49,6 +53,8 @@ neighboring chunk to be present. Similarly, once we have the terrain composition generate all the vegetation and structures in it, and those can again use the terrain composition in neighboring chunks.

+ +

The ComposableGenerator pipeline

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 @@ -61,6 +67,7 @@ sequence:

  • Finishers
  • + @@ -69,6 +76,8 @@ sequence: have 5 biome generators and 3 height generators and you can let the users mix'n'match.

    + +

    Using coherent noise for the generation

    For a great tutorial on coherent noise, see the LibNoise documentation.

    @@ -79,41 +88,180 @@ documentation.

    parameters are given to the noise functions.
  • The noise can be seamlessly extended in any direction
  • +

    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:

    - + +

    It comes only naturally that such a 2D noise can be used as a terrain height map directly:

    - + +

    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.

    + +

    Generating biomes

    -

    The easiest way to generate biomes is to not generate 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 +

    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.

    +

    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 biomes.

    +

    Voronoi diagram

    -

    These two generators are more of a technicality, we need to make something more interesting if we're +

    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 Voronoi diagram 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:

    + +

    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.

    +

    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.

    +

    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]:

    - + +

    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 5 x 5 seeds around it:

    - +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.

    + + +

    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.

    + +

    Here's an example of a biome map generated using the Voronoi + jitter grid, as implemented by the Voronoi +biome generator in MCServer:

    + + +

    Distorted Voronoi

    +

    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].

    + +

    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:

    + +DistortedVoronoiBiome(X, Z) := VoronoiBiome(X + PerlinX(X, Z), Z + PerlinZ(X, Z)) + + +

    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:

    + + +

    As you can see, this already looks reasonable enough, it could be considered natural biomes, if it +weren't for several drawbacks: +

      +
    • There's no way to limit the neighbors. A desert biome can neighbor a tundra biome.
    • +
    • 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.
    • +

    + +

    Adding relativity

    +

    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 boundaries 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.

    + +

    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.

    + +

    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:

    + + +

    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:

    + + +

    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: +

      +
    • Decide whether the point is in the ocean, land or mushroom
    • +
    • If it's land, decide if it's real land or river.
    • +
    • If it's real land, use a TemperatureHumidity approach to generate land-biomes
    • +
    +

    + +

    This is the approach implemented in MCServer's MultiStepMap biome generator. It generates biome maps like +this:

    + + +

    To decide whether the point is in the ocean, land or mushroom, the generator uses a DistortedVoronoi +approach where the seeds get the "ocean", "land" and "mushroom" values; special handling is added so that a +mushroom value is always surrounded by ocean values on all 8 sides:

    + + +

    For the Voronoi cells 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:

    + + +

    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:

    + + +

    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.

    + +

    Two-level Voronoi

    +

    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 +Voronoi generator.

    + +

    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.

    + +

    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.

    +
    +
    +
    + +

    The following image shows an example output of a TwoLevel biome generator in MCServer:

    + + + + +

    Terrain height

    diff --git a/docs/img/biomes.jpg b/docs/img/biomes.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0f7a31eea9c80a926cf943d326470824a7cd2464 GIT binary patch literal 34538 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 literal 0 HcmV?d00001 diff --git a/docs/img/distortedvoronoibiomes.png b/docs/img/distortedvoronoibiomes.png new file mode 100644 index 0000000000000000000000000000000000000000..d56dff347cb8c3ca24f5acc1946ddf232453be40 GIT binary patch literal 6012 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 KRKu_S|4jfvqA4Q) literal 0 HcmV?d00001 diff --git a/docs/img/jittergrid.jpg b/docs/img/jittergrid.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a13fae9233a0833b68e3f5f6a5e0126289217c86 GIT binary patch literal 51390 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

    cHPH{WLGiymlBu}Lu> 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

    LAICcJ~n$zax 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 literal 0 HcmV?d00001 diff --git a/docs/img/perlin.jpg b/docs/img/perlin.jpg new file mode 100644 index 0000000000000000000000000000000000000000..499fcdeaea76fd15b792d1c790f1b7392394e029 GIT binary patch literal 24105 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 literal 0 HcmV?d00001 diff --git a/docs/img/temperaturehumiditydecisionsimple.jpg b/docs/img/temperaturehumiditydecisionsimple.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b6cf916f6ce5292985ee87583a409adb926c8183 GIT binary patch literal 51736 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

    Hp4Fw}SB)Anu;oWf_rg&1F)X`fykG!9sKD$#x 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

    1n9eo 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

    C&!H($Orio|d|wsj75 zELXjI&mgZsFnv+g_sC^2gvO}`hNMEj(@ZEMcrM+>+f$R%^|2Q3KFn#sV_>EGUlg)n6w4H zORLdJeozL$1WY~tb>rom%&y6zSzegF!BQuHCOhfxo^TofE*OdoHe?&bzqM%842fkw zeqiE#iqh{q`;l=&G*P?NEHF!3VN4WrdR=eb;_&%pu2Kh_2Ryv?>G;D52hJ;Dde<NPlzu38M9tEjEpX!A{cTMUBn%D&0;NR~$=>o@rp;G}9yN z2LeglMw#|>D0v$G1WA}~d){g_xcx&)L@EPXk=Osje8;Gu!u+-X(;@q+Cr>LKT8=(t zD}vTMj~us2QaP4VqYwNT{S#!hN@gC=Gg`+ZZymLFadt2qUz@%e6;ql+loz;8*2E^Mfxr+{nyPRp^1&HIcPXi#EFadBI0p%uw!VJPi$(5+WmnY5 zI6~FJ#VEUSW?JBZn7eZb@O0{ur|7b5|EB1If*XbkMKVf(2m4<_!&)^o8KBdhn}>{+ z@opIxc16rJ2tg;CAw|7QxoprI+(G>}Ddg2HPU-5mo1~!SkDB#Eo(LYFoqJ?@*4vfW{-cTWsDC^1b81-C0n_H=WT~m6H2_tgp z$+QCJlyW7=2IX~L#o_DPAI?Gd`Sm&!8MaCh*unf>t=BOr ztFRMrY2B<#N@Y&{=)fW8x#K*WC^w~cnwmb%COo8Asb=$(XEGPliiA~1mi%ia%Qo5m zL~gudGoB%{B)H*44&Q_4x28A<_U(7pfJ)^q5G(%gtEsP|j^Is}=QKoF$979-vP=c zw)lF3=1AU8rQ1=vGr`e5E+_ia+{^rxBE~XXI>IJUCwoU0i!@~O_2&Mtd{_IpgY{0= mW^+3N7?Bwk-Y8#6`NH%h`xjd=3Bcz6J|Fo1aLn-Y`@aE`#9({? literal 0 HcmV?d00001 diff --git a/docs/img/twolevelbiomes.png b/docs/img/twolevelbiomes.png new file mode 100644 index 0000000000000000000000000000000000000000..a3104733ff9b6bd42b3f41e7e4725895de548907 GIT binary patch literal 33816 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 Wf`%ct`+(slNLSnNVU?!i>;DHXX)V?O literal 0 HcmV?d00001 diff --git a/docs/img/voronoijitterbiomes.png b/docs/img/voronoijitterbiomes.png new file mode 100644 index 0000000000000000000000000000000000000000..42f0b7e40e049ea92e904d6031b1fcf50418a1d2 GIT binary patch literal 4268 zcmX9?dpy(KAOFrR_d65jGLKtg6NTjRgi>zR`sMP(hD0g%Hfc#7GM9KNF-`PP)4G^T zJyV#OTOs9=$ry9bnr$)Ht!9{`{na?Jhr)5)dWac=zd5!E#I+^|&5 zZu`s#iE~m_%IfI{#O|sD7+#W2kUA%ES{k$atW=Z!!6-vjiCwhbm87+;({H+2u(k*; z2b~DK=u4n_0$kWM987CB>q7mdaqwgJ2d^CT*tkm}R_;%u*ww5#Z$x^ti_jdT0Zb+NNB_#x}rl<-z zrQ?1)2~-fI02f?|iAgf@X&K%LEJ@Li7U^b?bnjIQ%|O>*O0F}RqDNq)d=7?!GfIL_cOKI&|~8Q|W8i-#JzdmhO}SpiS<>R}BA) zV(g8U_k-lBJ>VMWmfjyFI$xR|)`fUk1m#+ewhnQ+#&>bNW%xhRtP)ecYoNUPXF-RA zDj~=tpUn?RjGRi^l7_=4#+Aktnc*Eh0dp&_`l%U#L1Xj25m$GjzmArqZ0|0` zDz&Ua=P!?21il-Pxa8Dew<^9PU^3S+pr|+5JT@bQz3+RJ6K$!&@x0kPsQXnZVo163 zbhN|U>y}dXr<3$Uk4w4F>r@ashMv##c&6yOxXjzlDB@*R#WyrBh z$VY)TG?mJ0Pq$ky5zW609NV=%<4lFlitAdx{Sbe^*haVshEky$;@)uzsN%d^FWs%$ zG_28mcAp0TwQ=$@GGrg~Wx;51+@B;$^&oFz&y9(#d%VqseY8YVR0RjIds#_-S~3}_kB$6U0~pzCmrx z$VZ@W*O$$&J}{hD7r9r%Nsd-vK2VPaP-UH8#;s_H{wjZ)B9~&^5Fx9h{;0dFK5B_o zlds+vH;%#6{MqVpkV(e&r-Jl_qmk?H9qU>pz=EwYP`q}y7n`d?NY92nis~OC(3A6C9-;79B0M)e zP@=<`I}3?Xww)|G^Q&KLJD8^5ZM~{J9^I(_F@Cyd{PL%v_8~$=SYBlY z<(?jLDM9>%L1%vjQ^s*aEU4GJ*<7>J{$jEy+@+POhL43MMK{^j7p#kEym^pKCelvNP0C2Pn;DRP8y4{qIgDgzwu-R?h~izjK} zDpy~2KovSDv*tII!=Dwkl=a_wCJ^!^-=~PVDtb(D4C_evoOsIthRYlQf~3-7RKfs~ zNe8B0MWup}A$0eaH}(|5sRWbgiFvGk(g1>Q1pbEZ@EooH6-N zx>Ieih`H#cj5c&GrHmGTk|%~RZDTAoWwek=0e--$3UXHv zA;&0mvEytzWA|bC5mziE-07qy0#+owp-6f9mSHN8HI5o>+WBKk^#N^0N1c-$flsMb z7f2dPiGne*&&&#a|PDpo=M>X@BBc1F|Bwdu*u zr$Mv@VY+tYiGk)+uDwads-9ThSsd(p|41%1Cbq@W?Oc~KN(3O3d4g~8Em8(vG$n3# zu6DGuQHWP!*NALR(}0H0T^Ey6K@n_YEj10P?+m88+1jAa)9v7Q89=z~RIUd;r3Fg! z^uXTim4=^EM)r0NUDF43;@bxA5cZ~>YEThpDEf7Mbcy`lvDe41SwXTuM(bf}vPXKy zTJl+^pTE1Fm(XIcHP~Mi@qd3MQBJ-v2-D7qF&&zbiwYCVkJ#G;Z3nAa3$5JJm?t)e zr;f5ULb<@{E?GLcZ~={j-L)3ZsX5W+=Xb`osX|`Mo{(eC2)e~#ENK5p@gJK9Qx~K5 z_O3-qUAvg%`2541>iJUk(=YpoCP=r&&z_)Eb=CtG3!Qu8_8Yc_A=UHTo+c=9iYd@# z7gb#QIHU!WAxjH9poszvL)z^cWtQPuSd;Br$W(5Y_bvbSb65|ovGJma9c(Fy=Ucg9*~OIv zjm;qGxEcQ3=$0yyX7B+xsu=6r4o21_)VLXm_SG+&m(x1KDWSRBxtJiaVT-RxD-zzx zv9lw;8{QBz8*$a3+w4zW3&tJq}8R|{Q5FEvkz?C8hJ$t`wS-ow$jZjTfaH}$qCRbmw z3xq3((!P%04Kb6Z%{mw6%?nylj0=tTml0HdHi}w70oy2u^JA7+l?P+YtMEM)+iELlZrgWN)hafn{SY^BQ zAbVP8{r&lH1kdRObgtxkVLj1w!qB^IFjEO;5-w{MO>zEb`6lypaN0(kqLy{|A~y+i zUbZii;+*>P&6jnwy|HyZ$*x9{&7F2{PuN~S_jXYVE{NP8sB-A}+QY(_y@mJ-xNwCV zs6~angG00u0GGzoofl}E;lpPlg(Ju22pvIg0|y{Rgk$9 z&r^k91ty7jpWOv^t?sQ_Yn1Nvr14bwlbt}@Y8>zyr*NfvcLMt(EoN|^fM$A)c=K((l zE^QQ~RI4-`ab>hQYkzwdTyPsMEIN|LS>#>O|2fjRMrEwS^B=-Y!t~FUQI27}XLM{1 zw-=M_T%e`M#|x`hH{dbdRR7;Tje;U-aspzyQ$kl5*8ik5XkJ!O3H$C5=-s;P{xGR4 zxg;IYPyn;YO2NfxS8N4j1jD0uo$KmwWnfOq*q(FT5q%I zh2fYlHLAEvR0TEkCkMDSJ7J3q;JtRHp<9p;Sh;E--l97`zOU7oEyA&L z+^^N0Q9Z<0?9ZtsP{3*vF2|c%8$5EM*!>$RisZG=ZFl)Z&ul?y<#{U;BwYuQ|G$j+ zg(D{pHbG}i!odQMv!YVSo$-%$f3qp$nCz4snCQNqaA|rlrnho8D>@iQu}Q7oa2yM8 zc*N^}*{#yX`Fdu$h|a{6#s|+$%gMh{k$M$`ocCZ?HE5=PJL=c68x{XjpkBt*oq8Nw!&(zb451Z2{g(n# z-4#VCK=P5n@#L<2LdmZyGEm|+#}@L@`2@B!AsYrT4-k^s+(t$Ins8}$8P=D@=q|o@ ziv+H*Oi0>#3&i^QV;TabtNvbaZ*VhMwG-;m01x(W!z8QKDq$WsHun4 z;+oie?ap`sml2CayiqrJOuB}o6S6iDA7bbh(8j9ZZ8;EMnf>ADeySUL`-iibylp0b z?uq6^EkE_AmYDo$!9t83olxH0XJ_05tf-79JoBR>+Im*x77Usq{&$-Hi1kFgQv8 literal 0 HcmV?d00001 From cdddb1aeac88d5502da43e238c670da5492d462f Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 1 Jun 2014 22:35:29 +0200 Subject: [PATCH 214/312] AnvilStats: Added new biome colors. --- Tools/AnvilStats/BiomeMap.cpp | 35 ++--------------------------------- Tools/AnvilStats/BiomeMap.h | 2 +- 2 files changed, 3 insertions(+), 34 deletions(-) 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); From fa78379f5a8a1eede69f36b225d684723b0bf3ae Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 2 Jun 2014 11:45:32 +0200 Subject: [PATCH 215/312] Updated OnProjectileHitBlock documentation. --- MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua index 1588d420c..67d670d0a 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 From 4c757de9ff58ddab07fa2a337a1359b707480288 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 2 Jun 2014 11:54:45 +0200 Subject: [PATCH 216/312] Added OnProjectileHitBlock example in Debuggers --- MCServer/Plugins/Debuggers/Debuggers.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 + + + + From 8cf4e806ba53aea8161f4110e8c3c67d215539eb Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 2 Jun 2014 13:49:05 +0200 Subject: [PATCH 217/312] APIDump: Fixed crash --- MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua index 67d670d0a..72cf85821 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnProjectileHitBlock.lua @@ -14,7 +14,7 @@ return { 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." + { 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 From b7dc4177d0cf7677b3e74f5a9bb89277df2b2ebd Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 2 Jun 2014 14:07:18 +0200 Subject: [PATCH 218/312] cBlockArea reading hotfix. This should fix the crashes introduced with chunksparsing. Not the most performant solution, but at least it should work. Ref.: #1056 --- src/BlockArea.cpp | 174 +++++++++++++++++++++++++++++----------------- 1 file changed, 110 insertions(+), 64 deletions(-) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 40fdd68c0..e3a859e4f 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -1835,87 +1835,133 @@ bool cBlockArea::cChunkReader::Coords(int a_ChunkX, int a_ChunkZ) -void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) +void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) { - { - if (m_Area.m_BlockTypes != NULL) - { - int SizeY = m_Area.m_Size.y; - int MinY = m_Origin.y; - - // 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; - int SizeZ = cChunkDef::Width; - int OffX, OffZ; - int BaseX, BaseZ; - OffX = m_CurrentChunkX * cChunkDef::Width - m_Origin.x; - if (OffX < 0) - { - BaseX = -OffX; - SizeX += OffX; // SizeX is decreased, OffX is negative - OffX = 0; - } - else - { - BaseX = 0; - } - OffZ = m_CurrentChunkZ * cChunkDef::Width - m_Origin.z; - if (OffZ < 0) - { - BaseZ = -OffZ; - SizeZ += OffZ; // SizeZ is decreased, OffZ is negative - OffZ = 0; - } - else - { - BaseZ = 0; - } - // If the chunk extends beyond the area in the X or Z axis, cut off the Size: - if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_Origin.x + m_Area.m_Size.x) - { - SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_Origin.x + m_Area.m_Size.x); - } - if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_Origin.z + m_Area.m_Size.z) - { - SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z); - } + int SizeY = m_Area.m_Size.y; + int MinY = m_Origin.y; - for (int y = 0; y < SizeY; y++) + // 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; + int SizeZ = cChunkDef::Width; + int OffX, OffZ; + int BaseX, BaseZ; + OffX = m_CurrentChunkX * cChunkDef::Width - m_Origin.x; + if (OffX < 0) + { + BaseX = -OffX; + SizeX += OffX; // SizeX is decreased, OffX is negative + OffX = 0; + } + else + { + BaseX = 0; + } + OffZ = m_CurrentChunkZ * cChunkDef::Width - m_Origin.z; + if (OffZ < 0) + { + BaseZ = -OffZ; + SizeZ += OffZ; // SizeZ is decreased, OffZ is negative + OffZ = 0; + } + else + { + BaseZ = 0; + } + // If the chunk extends beyond the area in the X or Z axis, cut off the Size: + if ((m_CurrentChunkX + 1) * cChunkDef::Width > m_Origin.x + m_Area.m_Size.x) + { + SizeX -= (m_CurrentChunkX + 1) * cChunkDef::Width - (m_Origin.x + m_Area.m_Size.x); + } + if ((m_CurrentChunkZ + 1) * cChunkDef::Width > m_Origin.z + m_Area.m_Size.z) + { + SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z); + } + + // Copy the blocktypes: + if (m_Area.m_BlockTypes != NULL) + { + for (int y = 0; y < SizeY; y++) + { + int InChunkY = MinY + y; + int AreaY = y; + for (int z = 0; z < SizeZ; z++) { - int ChunkY = 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 ChunkZ = BaseZ + z; - int AreaZ = OffZ + z; - for (int x = 0; x < SizeX; x++) - { - int ChunkX = BaseX + x; - int AreaX = OffX + x; - m_Area.m_BlockTypes[m_Area.MakeIndex(AreaX, AreaY, AreaZ)] = a_BlockBuffer.GetBlock(ChunkX, ChunkY, ChunkZ); - } // for x - } // for z - } // for y - } + 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 } + // Copy the block metas: if (m_Area.m_BlockMetas != NULL) { - a_BlockBuffer.CopyMetas(m_Area.m_BlockMetas); + 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 } + // Copy the blocklight: if (m_Area.m_BlockLight != NULL) { - a_BlockBuffer.CopyBlockLight(m_Area.m_BlockLight); + 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 } + // Copy the skylight: if (m_Area.m_BlockSkyLight != NULL) { - a_BlockBuffer.CopySkyLight(m_Area.m_BlockSkyLight); + 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 } - } From b9ca7bd1203f704d4f9d6215d72728d40a187b7c Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Mon, 2 Jun 2014 14:16:36 +0200 Subject: [PATCH 219/312] Small tweak for mobs Mobs move a bit smoother and aren't able to move allot when in air. --- src/Mobs/Monster.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) 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 From 345d4778499494616a0fac8568fbefa881627285 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 2 Jun 2014 21:43:07 +0200 Subject: [PATCH 220/312] Generator article: Finished the Biome-gen section and images. --- docs/Generator.html | 39 +++++++++++++++++++----------- docs/img/multistepmapdistance.jpg | Bin 0 -> 44859 bytes docs/img/multistepmapgrid.jpg | Bin 0 -> 62455 bytes docs/img/perlinrivers.jpg | Bin 0 -> 58103 bytes docs/img/twolevellargeareas.jpg | Bin 0 -> 47661 bytes docs/img/twolevelsmallareas.jpg | Bin 0 -> 67231 bytes docs/img/twolevelsmallgrid.jpg | Bin 0 -> 122477 bytes docs/img/voronoi.png | Bin 0 -> 19306 bytes 8 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 docs/img/multistepmapdistance.jpg create mode 100644 docs/img/multistepmapgrid.jpg create mode 100644 docs/img/perlinrivers.jpg create mode 100644 docs/img/twolevellargeareas.jpg create mode 100644 docs/img/twolevelsmallareas.jpg create mode 100644 docs/img/twolevelsmallgrid.jpg create mode 100644 docs/img/voronoi.png diff --git a/docs/Generator.html b/docs/Generator.html index b7586a183..0963f8505 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -109,7 +109,7 @@ biome generator does.

    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 biomes.

    +generates a grid of alternating biomes.

    Voronoi diagram

    Those two generators were more of a technicality, we need to make something more interesting if we're @@ -117,7 +117,7 @@ going for a natural look. The Voronoi generator is the first step towards such a Voronoi diagram 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:

    - +

    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 @@ -218,19 +218,24 @@ either add them somewhere into the decision diagram, or we can make the generato this:

    -

    To decide whether the point is in the ocean, land or mushroom, the generator uses a DistortedVoronoi -approach where the seeds get the "ocean", "land" and "mushroom" values; special handling is added so that a -mushroom value is always surrounded by ocean values on all 8 sides:

    - +

    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:

    + -

    For the Voronoi cells 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:

    - +

    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:

    +

    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:

    - +

    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 @@ -239,7 +244,7 @@ into FrozenOcean, and the River biome into FrozenRiver, wherever the temperature

    Two-level Voronoi

    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 -Voronoi generator.

    +DistortedVoronoi generator.

    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. @@ -253,13 +258,19 @@ the nearest seed's distance, but also the distance to the second-nearest seed; t 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.

    -
    -
    -
    + +

    The images below illustrate the process with regular Voronoi diagrams, for clarity purposes. The real +generator uses distortion before querying the small areas.

    +
    +
    +

    The following image shows an example output of a TwoLevel biome generator in MCServer:

    +

    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.

    +

    Terrain height

    diff --git a/docs/img/multistepmapdistance.jpg b/docs/img/multistepmapdistance.jpg new file mode 100644 index 0000000000000000000000000000000000000000..74e972b2a1804f4ae12b206e8ac247cde26cd31c GIT binary patch literal 44859 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

    * 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 Pm8(BjvHl;{KY#oeroe`I literal 0 HcmV?d00001 diff --git a/docs/img/multistepmapgrid.jpg b/docs/img/multistepmapgrid.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7e7bf870f44d2567329bc94f8c4341fdfd3b4bf4 GIT binary patch literal 62455 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 literal 0 HcmV?d00001 diff --git a/docs/img/twolevellargeareas.jpg b/docs/img/twolevellargeareas.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4d6b418b15b28584afb1b4d10cdc2254dd7fc097 GIT binary patch literal 47661 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 Gp7>u}j*dM5 literal 0 HcmV?d00001 diff --git a/docs/img/twolevelsmallareas.jpg b/docs/img/twolevelsmallareas.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8bfa54ab3c38c8e5ccd14bff2a7f0d10bd8ebabe GIT binary patch literal 67231 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 literal 0 HcmV?d00001 diff --git a/docs/img/voronoi.png b/docs/img/voronoi.png new file mode 100644 index 0000000000000000000000000000000000000000..e61e183ef5582dd6457983c9bda62c14780a2efe GIT binary patch literal 19306 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 Date: Mon, 2 Jun 2014 21:56:59 +0200 Subject: [PATCH 221/312] Generator article: fixed bad wording. --- docs/Generator.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Generator.html b/docs/Generator.html index 0963f8505..d965cf5d2 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -181,9 +181,9 @@ generated right next to other land biomes.

    Adding relativity

    -

    Our next goal is to remove the first defect of the distorted voronoi generator: unrelated biomes +

    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 boundaries as possible. We could further improve on the selection of +want to have as few of such 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.

    Recall how we talked about the nature, where the biomes are formed by the specific conditions of a place. From 545478802b7a8b81ecb9d20ad3355eff1427f575 Mon Sep 17 00:00:00 2001 From: Joannis Date: Tue, 3 Jun 2014 09:26:14 +0200 Subject: [PATCH 222/312] - Added doxy comments and exported to lua - Manipulation of the ShootVector is not to be done by the function that wants to spawn a projectile. --- src/BlockEntities/DispenserEntity.cpp | 74 +++++++++++++++++++++------ src/BlockEntities/DispenserEntity.h | 12 ++--- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index db1b405cd..043a140e3 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -146,7 +146,18 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_FIRE_CHARGE: { - SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFireCharge); + if(Meta == E_META_DROPSPENSER_FACING_YP || Meta == E_META_DROPSPENSER_FACING_YM) + { + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFireCharge, GetShootVector(a_Chunk) * 20); + } + else + { + Vector3d ShootVector = GetShootVector(a_Chunk); + ShootVector = ShootVector * 20; + + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFireCharge, ShootVector); + } + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; @@ -154,7 +165,19 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_ARROW: { - SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkArrow); + if(Meta == E_META_DROPSPENSER_FACING_YP || Meta == E_META_DROPSPENSER_FACING_YM) + { + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkArrow, GetShootVector(a_Chunk) * 20); + } + else + { + Vector3d ShootVector = GetShootVector(a_Chunk); + ShootVector = ShootVector * 20; + ShootVector.y = ShootVector.y + 1; + + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkArrow, ShootVector); + } + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; @@ -162,8 +185,19 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_SNOWBALL: { - // Not working as there is no such entity yet? - SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkSnowball); + if(Meta == E_META_DROPSPENSER_FACING_YP || Meta == E_META_DROPSPENSER_FACING_YM) + { + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkSnowball, GetShootVector(a_Chunk) * 20); + } + else + { + Vector3d ShootVector = GetShootVector(a_Chunk); + ShootVector = ShootVector * 20; + ShootVector.y = ShootVector.y + 1; + + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkSnowball, ShootVector); + } + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; @@ -171,8 +205,19 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_EGG: { - // Not working as there is no such entity yet? - SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkEgg); + if(Meta == E_META_DROPSPENSER_FACING_YP || Meta == E_META_DROPSPENSER_FACING_YM) + { + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkEgg, GetShootVector(a_Chunk) * 20); + } + else + { + Vector3d ShootVector = GetShootVector(a_Chunk); + ShootVector = ShootVector * 20; + ShootVector.y = ShootVector.y + 1; + + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkEgg, ShootVector); + } + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; @@ -180,7 +225,8 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) case E_ITEM_FIREWORK_ROCKET: { - SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFirework); + SpawnProjectileFromDispenser(a_Chunk, DispX, DispY, DispZ, cProjectileEntity::pkFirework, GetShootVector(a_Chunk) * 0); + m_Contents.ChangeSlotCount(a_SlotNum, -1); break; @@ -196,15 +242,14 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) -void cDispenserEntity::SpawnProjectileFromDispenser(cChunk & a_Chunk, int & a_DispX, int & a_DispY, int & a_DispZ, cProjectileEntity::eKind a_kind) +void cDispenserEntity::SpawnProjectileFromDispenser(cChunk & a_Chunk, int & a_DispX, int & a_DispY, int & a_DispZ, cProjectileEntity::eKind a_kind, Vector3d a_ShootVector) { - Vector3d Angle = GetShootVector(a_Chunk); cChunk * DispChunk = a_Chunk.GetRelNeighborChunkAdjustCoords(a_DispX, a_DispZ); double EntityX = 0.5 + (a_DispX + DispChunk->GetPosX() * cChunkDef::Width); double EntityZ = 0.5 + (a_DispZ + DispChunk->GetPosZ() * cChunkDef::Width); - m_World->CreateProjectile((double) EntityX, (double) a_DispY + 0.5, (double) EntityZ, a_kind, NULL, NULL, &Angle); + m_World->CreateProjectile((double) EntityX, (double) a_DispY + 0.5, (double) EntityZ, a_kind, NULL, NULL, &a_ShootVector); } @@ -223,7 +268,7 @@ Vector3d cDispenserEntity::GetShootVector(cChunk & a_Chunk) m.Init(Vector3d(), 0, 180, 0); Look = m.Transform(Vector3d(0, 1, 0)); - return Look * 20; // UP + return Look; // UP } case E_META_DROPSPENSER_FACING_YM: @@ -231,7 +276,7 @@ Vector3d cDispenserEntity::GetShootVector(cChunk & a_Chunk) m.Init(Vector3d(), 0, -360, 0); Look = m.Transform(Vector3d(0, -1, 0)); - return Look * 20;; // DOWN + return Look; // DOWN } case E_META_DROPSPENSER_FACING_XM: Direction = 90; break; // WEST @@ -243,10 +288,7 @@ Vector3d cDispenserEntity::GetShootVector(cChunk & a_Chunk) m.Init(Vector3d(), 0, Direction, 0); Look = m.Transform(Vector3d(0, 0, 1)); - Vector3d Angle = Look * 20; - Angle.y = Angle.y + 1; - - return Angle; + return Look; } diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index adbe2070c..558cf41c5 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -22,6 +22,12 @@ public: static const char * GetClassStatic(void) { return "cDispenserEntity"; } + /** Spawns a projectile of the given kind in front of the dispenser */ + void SpawnProjectileFromDispenser(cChunk & a_Chunk, int & a_DispX, int & a_DispY, int & a_DispZ, cProjectileEntity::eKind a_kind, Vector3d a_ShootVector); // tolua_export + + /** Returns how to aim the projectile */ + Vector3d GetShootVector(cChunk & a_Chunk); // tolua_export + private: // cDropSpenser overrides: virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override; @@ -29,12 +35,6 @@ private: /// If such a bucket can fit, adds it to m_Contents and returns true bool ScoopUpLiquid(int a_SlotNum, short a_BucketItemType); - // Spawns a projectile of the given kind in front of the dispenser - void SpawnProjectileFromDispenser(cChunk & a_Chunk, int & a_DispX, int & a_DispY, int & a_DispZ, cProjectileEntity::eKind a_kind); - - // Returns how to aim the projectile - Vector3d GetShootVector(cChunk & a_Chunk); - /// If the a_BlockInFront is liquidable and the empty bucket can fit, does the m_Contents processing and returns true bool EmptyLiquidBucket(BLOCKTYPE a_BlockInFront, int a_SlotNum); } ; // tolua_export From 49b39f97e0d947c655aad64317a6500f94ad61ef Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 3 Jun 2014 14:00:50 +0200 Subject: [PATCH 223/312] Generator article: Added TOC with links. --- docs/Generator.html | 51 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/docs/Generator.html b/docs/Generator.html index d965cf5d2..d7eb6ba8d 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -8,7 +8,24 @@ specific to MCServer, though, it can be viewed as a generic guide to various terrain-generating algorithms, with specific implementation notes regarding MCServer.

    -

    Preface: How it's done in real life

    +

    Contents: +

    +

    + + +
    + +

    Preface: How it's done in real life

    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 @@ -21,7 +38,10 @@ mainly because in the nature everything interacts with everything. If a mountain 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.

    -

    Expected properties

    + +
    + +

    Expected properties

    For a MineCraft-like game terrain generator we need the generator to have several properties:

    @@ -304,16 +305,69 @@ using the same approach as in MultiStepMap - by using a thresholded 2D Perlin no

    Terrain height

    +

    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.

    + +

    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.

    + +

    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:

    + + +

    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:

    + + +

    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)):

    + + +

    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 Expected property - 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.

    + +

    (TODO: height with variations (N/A in MCS yet)


    Terrain composition

    +

    (TODO)


    Finishers

    +

    (TODO)

    + + +
    + +

    Making it all faster

    +

    (TODO)

    diff --git a/docs/img/biomalheights.jpg b/docs/img/biomalheights.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a01faef87ee20527f4f086cdd7402e2b2663b3b3 GIT binary patch literal 77747 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 literal 0 HcmV?d00001 diff --git a/docs/img/biomeheightsavg.jpg b/docs/img/biomeheightsavg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c8217cafcaa4cd18a13f54a26209cfe3192acc65 GIT binary patch literal 14946 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 rKA%ff^V}mhD Date: Thu, 5 Jun 2014 12:26:27 +0200 Subject: [PATCH 250/312] - Fixed a lot of alignment --- src/BlockEntities/DispenserEntity.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 475125719..97e25ca6d 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -196,7 +196,7 @@ 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, Vector3d a_ShootVector) { - if( a_Kind != cProjectileEntity::pkFireCharge ) + if (a_Kind != cProjectileEntity::pkFireCharge) { a_ShootVector.y = a_ShootVector.y + 1; } @@ -209,14 +209,14 @@ Vector3d cDispenserEntity::GetShootVector(NIBBLETYPE & a_Meta) { switch(a_Meta) { - case E_META_DROPSPENSER_FACING_YP: return Vector3d(0, 1, 0); // UP - case E_META_DROPSPENSER_FACING_YM: return Vector3d(0, -1, 0); // DOWN + case E_META_DROPSPENSER_FACING_YP: return Vector3d( 0, 1, 0); // UP + case E_META_DROPSPENSER_FACING_YM: return Vector3d( 0, -1, 0); // DOWN - case E_META_DROPSPENSER_FACING_XM: return Vector3d(-1, 0, 0); // WEST - case E_META_DROPSPENSER_FACING_XP: return Vector3d(1, 0, 0); // EAST + case E_META_DROPSPENSER_FACING_XM: return Vector3d(-1, 0, 0); // WEST + case E_META_DROPSPENSER_FACING_XP: return Vector3d( 1, 0, 0); // EAST - case E_META_DROPSPENSER_FACING_ZM: return Vector3d(0, 0, -1); - case E_META_DROPSPENSER_FACING_ZP: return Vector3d(0, 0, 1); + case E_META_DROPSPENSER_FACING_ZM: return Vector3d( 0, 0, -1); + case E_META_DROPSPENSER_FACING_ZP: return Vector3d( 0, 0, 1); } return Vector3d(0, 1, 0); From 413d90420d9061a33301a9f4c4dd43e3dbf5a393 Mon Sep 17 00:00:00 2001 From: worktycho Date: Thu, 5 Jun 2014 11:59:06 +0100 Subject: [PATCH 251/312] Start of GPU section. --- docs/Generator.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/Generator.html b/docs/Generator.html index 282e4c412..304220eb2 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -20,6 +20,7 @@ with specific implementation notes regarding MCServer.

  • Terrain composition
  • Finishers
  • Making it all faster
  • +
  • Excuting a GPU
  • @@ -369,5 +370,9 @@ would become impossible to apply the averaging.

    Making it all faster

    (TODO)

    +

    Executing on a GPU

    +

    Much of the terain genertion 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 three chunks in parallel.

    From c5343172c118ba59e3181777fbbfd99497d78d6d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 5 Jun 2014 12:01:02 +0100 Subject: [PATCH 252/312] Typographical error --- docs/Generator.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Generator.html b/docs/Generator.html index 304220eb2..860144338 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -20,7 +20,7 @@ with specific implementation notes regarding MCServer.

  • Terrain composition
  • Finishers
  • Making it all faster
  • -
  • Excuting a GPU
  • +
  • Executing a GPU
  • From 523d29b84567888b0e8876ddb1b08d73dae10597 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 5 Jun 2014 21:25:18 +0200 Subject: [PATCH 253/312] docs/Generator: Added basic terrain composition. --- docs/Generator.html | 32 +++++++++++++++++++++++++++++++- docs/img/perlincompositor1.jpg | Bin 0 -> 15457 bytes docs/img/perlincompositor2.jpg | Bin 0 -> 29005 bytes docs/img/perlincompositor3.jpg | Bin 0 -> 21119 bytes 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 docs/img/perlincompositor1.jpg create mode 100644 docs/img/perlincompositor2.jpg create mode 100644 docs/img/perlincompositor3.jpg diff --git a/docs/Generator.html b/docs/Generator.html index 860144338..4647a2165 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -341,7 +341,7 @@ than the columns further away. The following image shows the output of MCServer' 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)):

    - +

    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 @@ -356,6 +356,36 @@ would become impossible to apply the averaging.


    Terrain composition

    +

    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 height averaging screenshot.

    + +

    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.

    + +

    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.

    + +

    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:

    + + + +

    (TODO)

    diff --git a/docs/img/perlincompositor1.jpg b/docs/img/perlincompositor1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0d8f93cd9f8ab097c5c2c8014f462067520a0f41 GIT binary patch literal 15457 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 WhNmW0qX!m#;7oX#iZ<+@ss9b!au8Sm literal 0 HcmV?d00001 diff --git a/docs/img/perlincompositor2.jpg b/docs/img/perlincompositor2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..11fc5b51d4dfb429c154a092d397a99ed9879f6c GIT binary patch literal 29005 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⁡)wwK3ug@o#K*>DKHXc|rMPaDG_FsLv_oYeZvoAH3hXLQ_Jrr_J&(MWs>rSguZCc^J>I7d|8=uH$`HIZB zzAQg~J3p$g%0I{TtZVz$QhBU9jX>n{PnW)=dv?AAqxt>r?R>0sH(HXaZI240pd0~I zRLNJ*^= zQ__GnAy1bkoWpG-Y&LUH&oJhI89ci|tc$ynGtF7KlOWbT-cD!%@!g%>YhK3e@y&AM zA*({pQV5_9iL9+Ae=(y0x}0zgHu^vp1AsbI5L|q{Y75!24>d7_V%v(`-mWUOXvQ^W z+K$(Ev72``3FfkHChN^jdp9SV%a%-s>pEz;t=W>O%NH~Onvr1ErI^MlzRVhuH`-_eZUP7ub{O{&SoYI$ zD{jSu5kMN&F!ZbXk@D*XjZX=574=zGSIRth!ooKm1sP1;<)oIbi zQ>jR{RfxXb0_~1iW>L^SRMQMIT-+qLr4=LP zV^f@;b6oW=IH;(!{{SzU>foGkwWn64SjwAD`s*v~xn8%wTWQ?TZLXMM!wyAJvS!n6 zgf4S!Dft`wr_!aCahhv^b8hh-q;P!?V_VdP{pjw$s~%<#5}|rEe}_H%yGePk#b|aq zV)U-2!FUzPY10lXr?8x0R;K~G3h`GUjFVKYr34DmjFS`W`}^^zlScL*l44P5?2xq`?nm|c>@Bq&xO{XwCgQ@uT73zAH7Xf zd&^h;UoD05R+?Z_Q&C+9QC+QuE1U6diyo(@%WmTjjnTJtVbIr7@+ywC&v=_tTPq1> z1AL!$G#y>f3Zv?4I;t)WPh&dD4xE)ut*OoE7jJc-+etV2)dn~EslonL4eiF<^G}8^ z?A;~{W?)?x=V9HCEPpa<+qpZ>SwS+d{WxcM!Vf4?aHl-)?L>gRnt9a*I<5`EfVn^z?99DwQb^T`+= zTA_RXsCwX37ck%6N}p&{Si#QKIjgscl&tB=&Tdw+(Cfz1h93=1ikg(KChYE&`BGQ; z9A>K6Cb_$b4&z;3tq0z&Ug{DU*5{N$kCR%q130XxqdBe3HWG2g0BXR$D5)80&9%AO zIH{W7+JGrWIjh#~j8uM3DZp)@3*L4Xsm(bik(}bHwo6b1g|}2PMVhe`WYoqkC<7Kq zaA_0eHK9CMsuBzu0JR+09csPZ#|N5#xfN3B$rJ%j?rf7(gXO97s}oI%B2P*Hy=uFN zt$TPu1B#(#5y;}Vts%%10bSw1=~SjnS4M4ey(*mcN78^f$r7tPe$~)Dk@Tn@&)R@F z=_4YlND7+hX0^cSS$9xi^q>mX@({wh4LWX>&m!TgR>`r70P115+P!J*eYd@1iAY+l zJmhzv4dvAEdeo;;$m?8>+D`7ZI$RUpfI2U>Zar%Kg!y63a?waht$jX17*GdaqFywS zVooKD>~ZcZsIt1oIj$>4R+4+0g&2xQ`8~kzT^+Guiq4B}3A48_ry6*PMjCCWX3}kZ zo}VMIvbxSWt@|nR2Q|dmJ7iZ!Vlo;+4nCFb`bU$C|T>j2f+jO?={$0N#kwO9}EWUdm3Kv`5?1@Tjha(rYR%@JqJ-r*>rr97LtkTF3k^Z@FpZYZha; z_oqo9Wi^h|?KI@M&wAA1BGh9H4Rd#P{{S)Kx=G(~HJdbhjR0cBZ}W7nhfB5T#a4n0 zu;RKMJ|&7HBk-y+O%2#_i<7e4vXRFGVWnk3>S{z-rd`oGxb~*n*bC3}o5duz+(Xd^ zZ^o)>HpfkoZf$a@oH~w`%PP}~=WE^keNS$NTZXMas>Y-CzMk#>0G9jtUu%{ohZRwy z=CqN;#kxqp#40ZqD3NG65T6CQw_X(=U}7Wp^E42FXh-S z zuUlym6TV<(ll#(h`3{1ebECl^&y*F1Mo*NF%9ZMGWKxC=d#+OTNn7r{+WWl>Ynx-w z6`3`$&r05s3%hOz`&3^1IR1vKw6^4s$uhV1OiiEAQSD;BEj>ZtD$80v`u^^}dfj}{ zf^7-yRpzl{+Pb8Ozxumbo85p>`kelhuWaM*S;&9gWk1Y{uV}xd%$^dW(b<37(f
    Oa6jN6{{SOVm$XBP3&wxjjF0I_)q>sFsNgXZ_#ox!ujO+Z z+Q@=9t-CvH0g*@AY$F--(ETb2Zyxcyn^iHycxOBl^r)UDoOXA9M_wBx#nyM693r=J zR!i^S(H36vHIT;yPdg5~IuFK(=Z0tUH?!SMbts5(N?V(ga2OWKDGsG_(h>^$h zTxaDA)K+tqN^$m*ew# z>yj{Qq7vtdcCqAQs45j@O-V}KR>wPa008k=7w7>s(_b*=xvfQpO1>Ese?hRW#Dy6}o3QSJww`>bysh_=CntE;`fG*oYPAgW{BBWH7HoJi0wFC(g VgCi;rRyd^Hw;W>R?G<)^|Ji^@M>PNd literal 0 HcmV?d00001 diff --git a/docs/img/perlincompositor3.jpg b/docs/img/perlincompositor3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..46a2583bacb13a375744e9866b439d7458be07a4 GIT binary patch literal 21119 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 Date: Fri, 6 Jun 2014 10:29:10 +0100 Subject: [PATCH 254/312] typo --- docs/Generator.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Generator.html b/docs/Generator.html index 4647a2165..758afa229 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -20,7 +20,7 @@ with specific implementation notes regarding MCServer.

  • Terrain composition
  • Finishers
  • Making it all faster
  • -
  • Executing a GPU
  • +
  • Executing on a GPU
  • From 2ed2f20a314e6c16244b61a228ab81242547ccfd Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 6 Jun 2014 11:38:29 +0100 Subject: [PATCH 255/312] Fixed numbers --- docs/Generator.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Generator.html b/docs/Generator.html index 758afa229..16aaf68c8 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -403,6 +403,7 @@ and use the layout corresponding to the threshold:

    Executing on a GPU

    Much of the terain genertion 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 three chunks in parallel.

    +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.

    From 702571024ca6893e62ffc4f36ff78873b55ff61c Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 6 Jun 2014 14:02:54 +0100 Subject: [PATCH 256/312] Expanded GPU section --- docs/Generator.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/Generator.html b/docs/Generator.html index 16aaf68c8..5def63e3b 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -404,6 +404,7 @@ and use the layout corresponding to the threshold:

    Much of the terain genertion 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.

    +in over 100 chunks in parallel. A naive comparison suggests a 800MHz a 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.

    From 8c8c3ba5c4dbdf85f10df6ba1ee3dd3f6b8438d0 Mon Sep 17 00:00:00 2001 From: worktycho Date: Fri, 6 Jun 2014 14:37:11 +0100 Subject: [PATCH 257/312] Grammar --- docs/Generator.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Generator.html b/docs/Generator.html index 5def63e3b..17690cd5c 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -404,7 +404,7 @@ and use the layout corresponding to the threshold:

    Much of the terain genertion 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 a 800MHz a GPU with 15,000 threads can execute parallel +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.

    From 5f56773dde8d06a291f42def9302ad932c490a28 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 6 Jun 2014 20:36:50 +0100 Subject: [PATCH 258/312] Further reduced redstone idle CPU consumption * Repeaters and wires are no longer unnecessarily ticked * Fixed #1063, likely addressed #1062 * Fixed bugs regarding duplicate values --- .../IncrementalRedstoneSimulator.cpp | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index fb8a3e81d..21326c7c4 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -209,7 +209,15 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, { return; } - + + 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)); } @@ -239,7 +247,7 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int { // 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); // + a_Chunk->SetIsRedstoneDirty(false); ShouldUpdateSimulateOnceBlocks = true; } @@ -253,13 +261,24 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int switch (dataitr->Data) { - case E_BLOCK_REDSTONE_WIRE: HandleRedstoneWire(dataitr->x, dataitr->y, dataitr->z); break; - case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(dataitr->x, dataitr->y, dataitr->z); break; + case E_BLOCK_DAYLIGHT_SENSOR: HandleDaylightSensor(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); + if (ShouldUpdateSimulateOnceBlocks) + { + HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); + break; + } + for (RepeatersDelayList::const_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); + break; + } + } break; } case E_BLOCK_WOODEN_PRESSURE_PLATE: @@ -277,10 +296,11 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int { 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_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; From 87603eb28064556e97d4630a2c03d4937c4e5f22 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 6 Jun 2014 19:45:17 +0200 Subject: [PATCH 259/312] Fixed a typo. --- docs/Generator.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Generator.html b/docs/Generator.html index 17690cd5c..e43838507 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -401,7 +401,7 @@ and use the layout corresponding to the threshold:

    (TODO)

    Executing on a GPU

    -

    Much of the terain genertion consists of doing the same thing for every single column or block in a chunk. This +

    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 From b768e54ce88819f3363b55879c0550b2830b3a56 Mon Sep 17 00:00:00 2001 From: archshift Date: Sat, 7 Jun 2014 00:40:01 -0700 Subject: [PATCH 260/312] Fixed mob hitbox sizes, removed TODOs Measured bat and blaze in vanilla, updated values. Cavespiders are, in fact, passive in the day. --- src/Mobs/Bat.cpp | 3 +-- src/Mobs/Blaze.cpp | 3 +-- src/Mobs/CaveSpider.cpp | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) 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..2a6a761bf 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) { } 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; } From d5649df326d90361bbf64e2ebb4893caa0499521 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 6 Jun 2014 23:23:28 +0100 Subject: [PATCH 261/312] Further improvements on redstone speed Based on suggestions of @worktycho * Repeaters now walk their data structure only when needed * Fixed a bug with cChunkData returning an incorrect value for whether a meta had changed --- src/ChunkData.cpp | 2 +- .../IncrementalRedstoneSimulator.cpp | 173 ++++++++++-------- src/Simulator/IncrementalRedstoneSimulator.h | 6 +- 3 files changed, 97 insertions(+), 84 deletions(-) diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 1fa2fd212..f2d220bd2 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -258,7 +258,7 @@ bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble (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; + return oldval != a_Nibble; } diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index 21326c7c4..aef332e9f 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -266,19 +266,20 @@ void cIncrementalRedstoneSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int case E_BLOCK_REDSTONE_REPEATER_OFF: case E_BLOCK_REDSTONE_REPEATER_ON: { - if (ShouldUpdateSimulateOnceBlocks) - { - HandleRedstoneRepeater(dataitr->x, dataitr->y, dataitr->z, dataitr->Data); - break; - } - for (RepeatersDelayList::const_iterator repeateritr = m_RepeatersDelayList->begin(); repeateritr != m_RepeatersDelayList->end(); ++repeateritr) + 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); + 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: @@ -746,7 +747,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: =================================== @@ -772,87 +773,99 @@ 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); - } - } - - for (RepeatersDelayList::iterator itr = m_RepeatersDelayList->begin(); itr != m_RepeatersDelayList->end(); ++itr) - { - if (!itr->a_RelBlockPos.Equals(Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ))) - { - continue; - } - - if (itr->a_ElapsedTicks >= itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks? - { - 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 - { - 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; - } - } - - // 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) - { - m_Chunk->SetBlock(a_RelBlockX, a_RelBlockY, a_RelBlockZ, E_BLOCK_REDSTONE_REPEATER_OFF, a_Meta); - } - m_RepeatersDelayList->erase(itr); // We can remove off repeaters which don't need further updating - return; - } + WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false); } 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++; + return; } } + else + { + return; + } + + if (WereItrsChanged) + { + for (a_Itr = m_RepeatersDelayList->begin(); a_Itr != m_RepeatersDelayList->end(); ++a_Itr) + { + if (a_Itr->a_RelBlockPos == Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) + { + break; + } + } + } + + if (a_Itr->a_ElapsedTicks >= a_Itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks? + { + if (a_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 + { + 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; + } + } + + // 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) + { + 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++; + } } @@ -1914,7 +1927,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) { @@ -1922,14 +1935,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; } } @@ -1944,7 +1957,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..83076311a 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); } From ec40c7c83ad1ef62b2c8e759bd9a76cf916f5e5b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 5 Jun 2014 23:44:31 +0200 Subject: [PATCH 262/312] Added RainbowRoads finisher generator. --- src/Generating/ComposableGenerator.cpp | 14 +- src/Generating/Prefabs/RainbowRoadPrefabs.cpp | 1406 +++++++++++++++++ src/Generating/Prefabs/RainbowRoadPrefabs.h | 15 + src/Generating/RainbowRoadsGen.cpp | 115 ++ src/Generating/RainbowRoadsGen.h | 47 + 5 files changed, 1594 insertions(+), 3 deletions(-) create mode 100644 src/Generating/Prefabs/RainbowRoadPrefabs.cpp create mode 100644 src/Generating/Prefabs/RainbowRoadPrefabs.h create mode 100644 src/Generating/RainbowRoadsGen.cpp create mode 100644 src/Generating/RainbowRoadsGen.h diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index cf736ce64..1801b7375 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -24,6 +24,7 @@ #include "NetherFortGen.h" #include "Noise3DGenerator.h" #include "POCPieceGenerator.h" +#include "RainbowRoadsGen.h" #include "Ravines.h" #include "UnderwaterBaseGen.h" #include "VillageGen.h" @@ -391,6 +392,13 @@ 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 MaxDepth = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxDepth", 30); + int MaxSize = a_IniFile.GetValueSetI("Generator", "RainbowRoadsMaxSize", 260); + m_FinishGens.push_back(new cRainbowRoadsGen(Seed, GridSize, MaxDepth, MaxSize)); + } else if (NoCaseCompare(*itr, "Ravines") == 0) { m_FinishGens.push_back(new cStructGenRavines(Seed, 128)); @@ -409,9 +417,9 @@ void cComposableGenerator::InitFinishGens(cIniFile & a_IniFile) } else if (NoCaseCompare(*itr, "UnderwaterBases") == 0) { - int GridSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseGridSize", 1024); - int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); - int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); + int GridSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseGridSize", 1024); + int MaxDepth = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxDepth", 7); + int MaxSize = a_IniFile.GetValueSetI("Generator", "UnderwaterBaseMaxSize", 128); m_FinishGens.push_back(new cUnderwaterBaseGen(Seed, GridSize, MaxDepth, MaxSize, *m_BiomeGen)); } else if (NoCaseCompare(*itr, "Villages") == 0) 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/RainbowRoadsGen.cpp b/src/Generating/RainbowRoadsGen.cpp new file mode 100644 index 000000000..d1e1f4bda --- /dev/null +++ b/src/Generating/RainbowRoadsGen.cpp @@ -0,0 +1,115 @@ + +// 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_OriginX, int a_OriginZ, + int a_MaxDepth, + int a_MaxSize + ) : + super(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_MaxDepth, int a_MaxSize) : + super(a_Seed, a_GridSize, a_GridSize, a_MaxSize, a_MaxSize, 100), + m_Noise(a_Seed + 9000), + m_MaxDepth(a_MaxDepth), + m_MaxSize(a_MaxSize) +{ +} + + + + + +cGridStructGen::cStructurePtr cRainbowRoadsGen::CreateStructure(int a_OriginX, int a_OriginZ) +{ + // Create a base based on the chosen prefabs: + return cStructurePtr(new cRainbowRoads(m_Seed, 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..acbd5abf9 --- /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_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_OriginX, int a_OriginZ) override; +} ; + + + + From 0544b96f8041e5dd31b4da84b52d23883d0853f0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 7 Jun 2014 13:59:10 +0200 Subject: [PATCH 263/312] docs/Generator: Added the easy Finishers. --- docs/Generator.html | 117 +++++++++++++++++++++++++++++++++++- src/Generating/CompoGen.cpp | 14 ++++- 2 files changed, 129 insertions(+), 2 deletions(-) diff --git a/docs/Generator.html b/docs/Generator.html index e43838507..3a7c57697 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -386,14 +386,129 @@ and use the layout corresponding to the threshold:

    +

    Nether composition

    +

    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.

    + +

    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. + +

    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.

    +

    (TODO)


    Finishers

    -

    (TODO)

    +

    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.

    +

    Snow

    +

    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 grass don't support snow, +for example.

    + +

    Ice

    +

    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.

    + +

    Bottom lava

    +

    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.

    + +

    Specific foliage

    +

    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.

    + +

    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.

    + +

    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.

    + +

    Small foliage

    +

    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:

    + + +

    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:

    + + +

    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:

    + + +

    (For the curious, there is a proof that adding together infinitely many uniform-distributed random number +produces random numbers with the Gaussian distribution.)

    + +

    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.

    + +

    Springs

    +

    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.

    + +

    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:

    + + +

    MCServer uses an approximation of the above curves to choose the height at which to generate the +spring.

    + +
    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); From 9ccdceaadf7aaf62d64d8d3406c46e71ef069210 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sat, 7 Jun 2014 16:41:18 +0200 Subject: [PATCH 264/312] docs/Generator: fixed grass confusion. --- docs/Generator.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/Generator.html b/docs/Generator.html index 3a7c57697..0fbc2f436 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -417,8 +417,8 @@ way.

    Snow

    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 grass don't support snow, -for example.

    +block, then checks whether the block supports snow on its top. Rails, levers and tall grass don't support +snow, for example.

    Ice

    Another example of an easy finisher. This scans through the world and turn each water block on the surface From e5da3097de669722ee10f99680e4077421601b5c Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sat, 7 Jun 2014 18:25:18 +0100 Subject: [PATCH 265/312] Corrected the furnace fuels. Solves #1071 --- MCServer/furnace.txt | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) 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 From 28b82d5bbb4a0c7df901bea9e9f65a66186379ec Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 8 Jun 2014 11:32:52 +0200 Subject: [PATCH 266/312] Proper fix for long interaction. Fixes #1078 and #1038. --- src/ClientHandle.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d47ceff0e..77f3b274a 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1089,18 +1089,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; } From c5d1ca7dac284bdce84fe42cc0932a432587d553 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Sun, 8 Jun 2014 20:54:41 +0100 Subject: [PATCH 267/312] Small change for easier understanding. --- MCServer/Plugins/APIDump/APIDesc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 1423d64bc..40bfe79ac 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -1969,7 +1969,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:

    function Callback({{cPlayer|cPlayer}})
    " }, ForEachWorld = { Params = "CallbackFunction", Return = "", Notes = "Calls the given callback function for each world. The callback function has the following signature:
    function Callback({{cWorld|cWorld}})
    " }, GetCraftingRecipes = { Params = "", Return = "{{cCraftingRecipe|cCraftingRecipe}}", Notes = "Returns the CraftingRecipes object" }, From b904223b9dbbe7b696dbd30e748bc131742e11ea Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 6 Jun 2014 22:31:16 +0200 Subject: [PATCH 268/312] Added queue for adding entities to cWorld. This alone doesn't work properly yet, further changes to cPlayer are needed. --- src/ClientHandle.h | 3 ++- src/Entities/Entity.h | 5 +++-- src/Entities/Player.cpp | 2 -- src/Entities/Player.h | 2 ++ src/World.cpp | 28 +++++++++++++++++++++++++++- src/World.h | 9 ++++++++- 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 659c67658..3f1cdf55a 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -250,7 +250,8 @@ 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 */ + /** Called when the player moves into a different world. + Locks the current world, doesn't lock the new world. */ void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket); /** Called when the player will enchant a Item */ diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 0c393c0f5..9fe771120 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -421,6 +421,9 @@ 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; @@ -485,8 +488,6 @@ protected: 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(); diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 3a9324d09..b83419903 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1595,8 +1595,6 @@ bool cPlayer::MoveToWorld(const char * a_WorldName) 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); World->AddPlayer(this); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index b7cb27d6c..83b9ad593 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -328,6 +328,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); diff --git a/src/World.cpp b/src/World.cpp index 88e9c32e6..ccd47d3b0 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -743,6 +743,17 @@ 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(); + } + m_ChunkMap->Tick(a_Dt); TickClients(a_Dt); @@ -2808,9 +2819,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 +2832,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); } diff --git a/src/World.h b/src/World.h index 98b241a2b..4c014a976 100644 --- a/src/World.h +++ b/src/World.h @@ -301,7 +301,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); @@ -926,6 +927,12 @@ 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; + cWorld(const AString & a_WorldName); virtual ~cWorld(); From af4a21ea0689107b377818574cb07dc4a2e8b755 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 8 Jun 2014 21:58:08 +0200 Subject: [PATCH 269/312] Fixed deadlock when moving players to other worlds. Fixes #1039, fixes #851 --- src/BlockID.h | 1 + src/ClientHandle.cpp | 21 ++---- src/ClientHandle.h | 6 +- src/Entities/Entity.cpp | 10 +-- src/Entities/Entity.h | 5 +- src/Entities/Player.cpp | 18 +++-- src/Items/ItemBoat.h | 2 +- src/Items/ItemBow.h | 2 +- src/Items/ItemFishingRod.h | 2 +- src/Items/ItemItemFrame.h | 2 +- src/Items/ItemMinecart.h | 2 +- src/Items/ItemPainting.h | 2 +- src/Mobs/Blaze.cpp | 2 +- src/Mobs/Ghast.cpp | 2 +- src/Mobs/Skeleton.cpp | 2 +- src/Mobs/Wither.cpp | 2 +- src/Mobs/Wither.h | 2 +- src/OSSupport/IsThread.cpp | 21 +++++- src/OSSupport/IsThread.h | 4 + src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.cpp | 15 +++- src/Protocol/Protocol125.h | 6 +- src/Protocol/Protocol132.cpp | 2 +- src/Protocol/Protocol16x.cpp | 4 +- src/Protocol/Protocol16x.h | 2 +- src/Protocol/Protocol17x.cpp | 15 +++- src/Protocol/Protocol17x.h | 6 +- src/Protocol/ProtocolRecognizer.cpp | 4 +- src/Protocol/ProtocolRecognizer.h | 2 +- src/Simulator/SandSimulator.cpp | 2 +- src/World.cpp | 111 ++++++++++++++++++++-------- src/World.h | 21 +++++- 32 files changed, 204 insertions(+), 96 deletions(-) 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/ClientHandle.cpp b/src/ClientHandle.cpp index 77f3b274a..e4bb9d8e9 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -327,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 @@ -356,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)) @@ -1753,18 +1753,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; { @@ -1774,7 +1764,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[] @@ -2379,9 +2368,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 3f1cdf55a..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); @@ -251,8 +251,8 @@ public: void SendData(const char * a_Data, size_t a_Size); /** Called when the player moves into a different world. - Locks the current world, doesn't lock the new world. */ - void MoveToWorld(cWorld & a_World, bool a_SendRespawnPacket); + 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..8f736a269 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; } diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index 9fe771120..85ad42d54 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 diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index b83419903..feb09b5d2 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -940,6 +940,8 @@ void cPlayer::Killed(cEntity * a_Victim) void cPlayer::Respawn(void) { + ASSERT(m_World != NULL); + m_Health = GetMaxHealth(); SetInvulnerableTicks(20); @@ -952,7 +954,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(); @@ -1583,19 +1585,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 - World->AddEntity(this); + // Queue adding player to the new world, including all the necessary adjustments to the object World->AddPlayer(this); return 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/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp index 2a6a761bf..19bdf8737 100644 --- a/src/Mobs/Blaze.cpp +++ b/src/Mobs/Blaze.cpp @@ -44,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/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/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/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/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 f7564fe6d..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) @@ -656,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: { @@ -984,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/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/World.cpp b/src/World.cpp index ccd47d3b0..ebe6b53e6 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -754,6 +754,9 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) m_EntitiesToAdd.clear(); } + // Add players waiting in the queue to be added: + AddQueuedPlayers(); + m_ChunkMap->Tick(a_Dt); TickClients(a_Dt); @@ -1642,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); } } @@ -1663,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); } } @@ -1674,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(); } @@ -1690,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(); } @@ -1713,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(); } @@ -1724,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, @@ -2240,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: @@ -2333,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); } @@ -2358,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); } } @@ -2977,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; @@ -2999,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; @@ -3129,6 +3126,63 @@ 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): + if (!m_ChunkMap->HasEntity((*itr)->GetUniqueID())) + { + m_ChunkMap->AddEntity(*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: @@ -3269,4 +3323,3 @@ void cWorld::cChunkGeneratorCallbacks::CallHookChunkGenerated (cChunkDesc & a_Ch - diff --git a/src/World.h b/src/World.h index 4c014a976..abdc3120c 100644 --- a/src/World.h +++ b/src/World.h @@ -284,8 +284,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 << @@ -933,6 +940,12 @@ private: /** 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(); @@ -970,6 +983,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 From ec0976f9b0ace946022f48fdb360830985e7ee14 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 9 Jun 2014 00:49:02 +0200 Subject: [PATCH 270/312] Fixed a crash when creating negative-size blockareas. Now the server emits a warning instead and continues execution. --- src/BlockArea.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index e3a859e4f..4fe6cd51e 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -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) From 8cfe6c973c21a10d6e2371917058f241e2679945 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 9 Jun 2014 01:42:03 +0200 Subject: [PATCH 271/312] docs/Generator: Added SmallFoliage illlustrations. --- docs/Generator.html | 4 ++++ docs/img/gaussprobability.jpg | Bin 0 -> 12994 bytes docs/img/roofprobability.jpg | Bin 0 -> 16679 bytes docs/img/smallfoliageclumps.jpg | Bin 0 -> 15867 bytes 4 files changed, 4 insertions(+) create mode 100644 docs/img/gaussprobability.jpg create mode 100644 docs/img/roofprobability.jpg create mode 100644 docs/img/smallfoliageclumps.jpg diff --git a/docs/Generator.html b/docs/Generator.html index 0fbc2f436..7b70033cb 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -483,6 +483,10 @@ height to find the third coord. If we want to generate clumps of mushrooms in th 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.

    +

    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.

    +

    Springs

    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 diff --git a/docs/img/gaussprobability.jpg b/docs/img/gaussprobability.jpg new file mode 100644 index 0000000000000000000000000000000000000000..77da24748102dac8d999260bcc16c6ecf648c567 GIT binary patch literal 12994 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 dN7`aZPSwYXA5iD literal 0 HcmV?d00001 diff --git a/docs/img/roofprobability.jpg b/docs/img/roofprobability.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e7a155113398e305b8dd23ef7539949d8ecda97a GIT binary patch literal 16679 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 C>b1TA literal 0 HcmV?d00001 diff --git a/docs/img/smallfoliageclumps.jpg b/docs/img/smallfoliageclumps.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4cc6cbc009dd496b06c962a76d8e5ff1c38be35f GIT binary patch literal 15867 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 literal 0 HcmV?d00001 From 02b509b81d4543a958caaad8389fa0cebd0a8e1a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 9 Jun 2014 17:05:22 +0200 Subject: [PATCH 272/312] ToLua can now be run in pure-lua mode. See the src/Bindings/AllToLua_lua.bat for usage example. --- lib/tolua++/src/bin/lua/_driver.lua | 93 +++++++++++++++++++++++++ lib/tolua++/src/bin/lua/basic.lua | 2 +- lib/tolua++/src/bin/lua/compat-5.1.lua | 9 ++- lib/tolua++/src/bin/lua/declaration.lua | 2 +- lib/tolua++/src/bin/lua/feature.lua | 2 +- src/Bindings/AllToLua_lua.bat.bat | 27 +++++++ 6 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 lib/tolua++/src/bin/lua/_driver.lua create mode 100644 src/Bindings/AllToLua_lua.bat.bat diff --git a/lib/tolua++/src/bin/lua/_driver.lua b/lib/tolua++/src/bin/lua/_driver.lua new file mode 100644 index 000000000..ec07573cb --- /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, "blamobdebug") +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/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 + + + + From 9b5e852f753ae56597bb1c099d6e403d301ae531 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 9 Jun 2014 20:00:17 +0200 Subject: [PATCH 273/312] Fixed debugging code in tolua++ driver script. --- lib/tolua++/src/bin/lua/_driver.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tolua++/src/bin/lua/_driver.lua b/lib/tolua++/src/bin/lua/_driver.lua index ec07573cb..21db96098 100644 --- a/lib/tolua++/src/bin/lua/_driver.lua +++ b/lib/tolua++/src/bin/lua/_driver.lua @@ -1,6 +1,6 @@ -- Allow debugging by ZBS, if run under the IDE: -local mobdebugfound, mobdebug = pcall(require, "blamobdebug") +local mobdebugfound, mobdebug = pcall(require, "mobdebug") if mobdebugfound then mobdebug.start() end -- The list of valid arguments that the ToLua scripts can process: From 3a3c42276e0c22d6a199a97bee7c9c5ec5c1a98e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 9 Jun 2014 21:18:20 +0200 Subject: [PATCH 274/312] docs/Generator: Fixed typo. --- docs/Generator.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Generator.html b/docs/Generator.html index 7b70033cb..90a92c553 100644 --- a/docs/Generator.html +++ b/docs/Generator.html @@ -474,7 +474,7 @@ By adding together two random numbers in the same range, we get the probability "roof" shape, enough for our needs:

    -

    (For the curious, there is a proof that adding together infinitely many uniform-distributed random number +

    (For the curious, there is a proof that adding together infinitely many uniform-distributed random numbers produces random numbers with the Gaussian distribution.)

    This scheme can be used to produce clumps of flowers, when we select the 2D coords of the clump center on From 2b45e720adc801ece3dc562772747791efc3567e Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 9 Jun 2014 21:35:46 +0200 Subject: [PATCH 275/312] Added Y coord checks and documentation to cBlockDoorHandler. --- src/Blocks/BlockDoor.h | 59 ++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index eaa039c50..bc59051c3 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -111,19 +111,19 @@ 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; } } @@ -137,29 +137,45 @@ public: static NIBBLETYPE IsOpen(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { - NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - return ((Meta & 0x4) != 0); + NIBBLETYPE Meta = GetCompleteDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); + return ((Meta & 0x04) != 0); } - /** Read the meta from the true part of the door and returns a meta with all infos include. */ - static NIBBLETYPE GetTrueDoorMeta(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) + /** 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 Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if ((Meta & 0x8) != 0) + if ((Meta & 0x08) != 0) { - NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); - return (DownMeta & 0x7) | 0x8 | (((Meta & 0x1) != 0) ? 16 : 0); + // The coords are pointing at the top part of the door + if (a_BlockX > 0) + { + NIBBLETYPE DownMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); + return (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 0x08 | (Meta << 4); } else { - NIBBLETYPE UpMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ); - return (Meta & 0x7) | (((UpMeta & 0x1) != 0) ? 16 : 0); + // 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 Meta | (UpMeta << 4); + } + // This is the bottom part of the door at the topmost layer of the world, there's no top: + return Meta; } } + /** 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); @@ -168,22 +184,27 @@ public: return; } - NIBBLETYPE Meta = GetTrueDoorMeta(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - bool Opened = (Meta & 0x4) != 0; - if (Opened == a_Open) + 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 & 0x7) ^ 0x4; - if ((Meta & 0x8) == 0) + 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 { - a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ, NewMeta); + // 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_BlockX, a_BlockY - 1, a_BlockZ, NewMeta); + } } } From bead36f5ed9ec9501ff9fa67bbaa8d734a7a168a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 9 Jun 2014 23:38:50 +0200 Subject: [PATCH 276/312] Added cRidgedMultiNoise, fixed cPerlinNoise. --- src/Noise.cpp | 170 +++++++++++++++++++++++++++++++++++++++++++++++++- src/Noise.h | 64 +++++++++++++++++++ 2 files changed, 233 insertions(+), 1 deletion(-) diff --git a/src/Noise.cpp b/src/Noise.cpp index 89115d992..9c7042b02 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] = std::abs(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] += std::abs(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 cOctaves; + + int m_Seed; + cOctaves m_Octaves; +} ; + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Inline function definitions: // These need to be in the header, otherwise linker error occur in MSVC From 9ff0ef87d4bca688b7fab8c7f4c9f9fcf683c06f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 9 Jun 2014 23:40:51 +0200 Subject: [PATCH 277/312] Added an experimental height generator, Mountains. --- src/Generating/HeiGen.cpp | 66 +++++++++++++++++++++++++++++++++++++++ src/Generating/HeiGen.h | 21 +++++++++++++ 2 files changed, 87 insertions(+) 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); @@ -300,6 +304,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: 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 { From 6c43799cc558a435a03d82218738a9ff57fb6702 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 10 Jun 2014 09:20:32 +0200 Subject: [PATCH 278/312] Fixed gcc compilation. --- src/Noise.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Noise.cpp b/src/Noise.cpp index 9c7042b02..e2e54efdf 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -1022,7 +1022,7 @@ void cRidgedMultiNoise::Generate2D( NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; for (int i = 0; i < ArrayCount; i++) { - a_Array[i] = std::abs(a_Workspace[i] * Amplitude); + a_Array[i] = abs(a_Workspace[i] * Amplitude); } // Add each octave: @@ -1038,7 +1038,7 @@ void cRidgedMultiNoise::Generate2D( NOISE_DATATYPE Amplitude = itr->m_Amplitude; for (int i = 0; i < ArrayCount; i++) { - a_Array[i] += std::abs(a_Workspace[i] * Amplitude); + a_Array[i] += abs(a_Workspace[i] * Amplitude); } } From 366ecf9dfd38d612c0685f3fbf8b3a95b9900697 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 10 Jun 2014 18:25:53 +0200 Subject: [PATCH 279/312] Fixed a race condition when adding a player to a world. --- src/ChunkMap.cpp | 24 ++++++++++++++++++++++++ src/ChunkMap.h | 4 ++++ src/World.cpp | 5 +---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 0a8164b47..dba6f3f41 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1665,6 +1665,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); diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 8786d7016..7e85bb6f1 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -199,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); diff --git a/src/World.cpp b/src/World.cpp index ebe6b53e6..6bcd1391a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -3148,10 +3148,7 @@ void cWorld::AddQueuedPlayers(void) (*itr)->SetWorld(this); // Add to chunkmap, if not already there (Spawn vs MoveToWorld): - if (!m_ChunkMap->HasEntity((*itr)->GetUniqueID())) - { - m_ChunkMap->AddEntity(*itr); - } + m_ChunkMap->AddEntityIfNotPresent(*itr); } // for itr - PlayersToAdd[] } // Lock(m_CSPlayers) From c259dad7b8561c9712c8e2c5c55d6399e9d26325 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 10 Jun 2014 18:27:17 +0200 Subject: [PATCH 280/312] Fixed clang warnings about abs() in Noise.cpp. MSVC provides a float overload of abs(), clang does not. Using the proper fabs(). --- src/Noise.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Noise.cpp b/src/Noise.cpp index e2e54efdf..040421106 100644 --- a/src/Noise.cpp +++ b/src/Noise.cpp @@ -1022,7 +1022,7 @@ void cRidgedMultiNoise::Generate2D( NOISE_DATATYPE Amplitude = FirstOctave.m_Amplitude; for (int i = 0; i < ArrayCount; i++) { - a_Array[i] = abs(a_Workspace[i] * Amplitude); + a_Array[i] = fabs(a_Workspace[i] * Amplitude); } // Add each octave: @@ -1038,7 +1038,7 @@ void cRidgedMultiNoise::Generate2D( NOISE_DATATYPE Amplitude = itr->m_Amplitude; for (int i = 0; i < ArrayCount; i++) { - a_Array[i] += abs(a_Workspace[i] * Amplitude); + a_Array[i] += fabs(a_Workspace[i] * Amplitude); } } From 1ff1a93866ab81e3868588a256f446a902a1a8c4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 10 Jun 2014 22:59:45 +0200 Subject: [PATCH 281/312] Initial Mesa Bryce implementation. --- src/Generating/DistortedHeightmap.cpp | 4 +- src/Generating/DistortedHeightmap.h | 6 +- src/Generating/HeiGen.cpp | 89 +++++++++++++++++++++++++++ src/Generating/HeiGen.h | 21 +++++++ 4 files changed, 116 insertions(+), 4 deletions(-) diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp index eb9fe92ba..e50f36d57 100644 --- a/src/Generating/DistortedHeightmap.cpp +++ b/src/Generating/DistortedHeightmap.cpp @@ -282,7 +282,7 @@ cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGen & a_BiomeGen) : m_OceanFloorSelect(a_Seed + 3000), m_MesaFloor(a_Seed + 4000), m_BiomeGen(a_BiomeGen), - m_UnderlyingHeiGen(a_Seed, a_BiomeGen), + m_UnderlyingHeiGen(a_Seed), m_HeightGen(m_UnderlyingHeiGen, 64), m_IsInitialized(false) { @@ -308,6 +308,8 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile) return; } + ((cTerrainHeightGen &)m_UnderlyingHeiGen).InitializeHeightGen(a_IniFile); + // Read the params from the INI file: m_SeaLevel = a_IniFile.GetValueSetI("Generator", "DistortedHeightmapSeaLevel", 62); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyX", 10); diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h index e6b3c9d3f..31fb17df2 100644 --- a/src/Generating/DistortedHeightmap.h +++ b/src/Generating/DistortedHeightmap.h @@ -64,9 +64,9 @@ protected: int m_CurChunkZ; NOISE_DATATYPE m_DistortedHeightmap[17 * 257 * 17]; - cBiomeGen & m_BiomeGen; - cHeiGenBiomal m_UnderlyingHeiGen; // This generator provides us with base heightmap (before distortion) - cHeiGenCache m_HeightGen; // Cache above m_UnderlyingHeiGen + cBiomeGen & m_BiomeGen; + cHeiGenMesaBryce m_UnderlyingHeiGen; // This generator provides us with base heightmap (before distortion) + cHeiGenCache m_HeightGen; // Cache above m_UnderlyingHeiGen /// Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. cChunkDef::HeightMap m_CurChunkHeights; diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 25ac912fd..dedf3fe3f 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, "MesaBryce") == 0) + { + res = new cHeiGenMesaBryce(a_Seed); + } else if (NoCaseCompare(HeightGenName, "Mountains") == 0) { res = new cHeiGenMountains(a_Seed); @@ -366,6 +370,91 @@ void cHeiGenMountains::InitializeHeightGen(cIniFile & a_IniFile) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cHeiGenMesaBryce: + +cHeiGenMesaBryce::cHeiGenMesaBryce(int a_Seed) : + m_Seed(a_Seed), + m_PerlinHFHA(a_Seed), + m_PerlinLFLA(a_Seed + 10) +{ +} + + + + + +void cHeiGenMesaBryce::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 Noise1[16 * 16]; + NOISE_DATATYPE Noise2[16 * 16]; + NOISE_DATATYPE Noise3[16 * 16]; + m_PerlinHFHA.Generate2D(Noise1, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); + m_PerlinLFLA.Generate2D(Noise2, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); + m_PerlinTops.Generate2D(Noise3, 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 = 70 + (int)(std::min(Noise1[idx], Noise2[idx]) * 15); + int hei; + if (Noise1[idx] > 1.5f) + { + hei = 83 + (int)floor(Noise3[idx]); + } + else + { + hei = 63 + (int)floor(Noise2[idx]); + } + /* + NOISE_DATATYPE v1 = sqrt(sqrt(std::max(Noise1[idx], (NOISE_DATATYPE)0))) - 50; + int hei = 60 + (int)floor(std::max(v1, 5 + Noise2[idx])); + */ + if (hei < 10) + { + hei = 10; + } + if (hei > 250) + { + hei = 250; + } + cChunkDef::SetHeight(a_HeightMap, x , z, hei); + } // for x + } // for z +} + + + + + +void cHeiGenMesaBryce::InitializeHeightGen(cIniFile & a_IniFile) +{ + // TODO: Read the params from an INI file + // m_PerlinHFHA.AddOctave(0.32f, 0.1); + /* + m_PerlinHFHA.AddOctave(0.13f, 17800000); + m_PerlinHFHA.AddOctave(0.12f, 19000000); + */ + m_PerlinHFHA.AddOctave(0.13f, 2); + m_PerlinHFHA.AddOctave(0.12f, 2); + + m_PerlinLFLA.AddOctave(0.04f, 1); + m_PerlinLFLA.AddOctave(0.02f, 2); + + m_PerlinTops.AddOctave(0.1f, 8); +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cHeiGenBiomal: diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index 5c106c7d9..5fc4f4abc 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -127,6 +127,27 @@ protected: +class cHeiGenMesaBryce : + public cTerrainHeightGen +{ +public: + cHeiGenMesaBryce(int a_Seed); + +protected: + int m_Seed; + cPerlinNoise m_PerlinHFHA; // HighFrequencyHighAmplitude, for the hills + cPerlinNoise m_PerlinLFLA; // LowFrequencyLowAmplitude, for the floor + cPerlinNoise m_PerlinTops; + + // 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 { From d5679f51dedc7998e56f683a876e5b22887a3488 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 11 Jun 2014 07:39:18 +0100 Subject: [PATCH 282/312] Removed derpbadge. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e6d9492f0..9e55001ef 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) [![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. From 5950212829e87041306f29754c3412389bc62390 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 11 Jun 2014 07:40:58 +0100 Subject: [PATCH 283/312] Test --- CONTRIBUTORS | 1 - 1 file changed, 1 deletion(-) 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. From fd2ff3845e444cb364efff6dcb101c9e7a583bf1 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 11 Jun 2014 08:49:33 +0100 Subject: [PATCH 284/312] Update GETTING-STARTED.md --- GETTING-STARTED.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GETTING-STARTED.md b/GETTING-STARTED.md index 1ac6fe989..4d992597e 100644 --- a/GETTING-STARTED.md +++ b/GETTING-STARTED.md @@ -10,7 +10,7 @@ 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 From 8695928dd17e96baed46da18d085b51f831e4bab Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 11 Jun 2014 09:37:00 +0100 Subject: [PATCH 285/312] Update GETTING-STARTED.md --- GETTING-STARTED.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/GETTING-STARTED.md b/GETTING-STARTED.md index 4d992597e..eb7d1b713 100644 --- a/GETTING-STARTED.md +++ b/GETTING-STARTED.md @@ -3,7 +3,7 @@ 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 possabile to contribute without knowing minecraft in detail though. I'd say that the important topics are: @@ -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. From 3e258523821e67a5892fe44dd585bae896866d9a Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 11 Jun 2014 10:04:34 +0100 Subject: [PATCH 286/312] Removed assert that is now informed by type system --- src/ByteBuffer.cpp | 1 - 1 file changed, 1 deletion(-) 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)) { From 7cb88e8c06a2d86f7563cac1e0911f51801a3dee Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 11 Jun 2014 10:21:24 +0100 Subject: [PATCH 287/312] Added coverity badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e55001ef..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) [![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. From c3c3782c67265f2844dc66667d3e6bc79a6b25ff Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 11 Jun 2014 10:33:16 +0100 Subject: [PATCH 288/312] Add new IsWeatherWet hook for cauldrons. @madmaxoft can you comment? --- src/World.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/World.h b/src/World.h index abdc3120c..b0fed84ba 100644 --- a/src/World.h +++ b/src/World.h @@ -708,12 +708,23 @@ public: eWeather GetWeather (void) const { return m_Weather; }; bool IsWeatherSunny(void) const { return (m_Weather == wSunny); } + bool IsWeatherSunny(int a_BlockX, int a_BlockZ) const { + return (m_Weather == wSunny) + } bool IsWeatherRain (void) const { return (m_Weather == wRain); } + bool IsWeatherRain (int a_BlockX, int a_BlockZ) const { + return (m_Weather == wRain) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))) + } bool IsWeatherStorm(void) const { return (m_Weather == wStorm); } + bool IsWeatherStorm(int a_BlockX, int a_BlockZ) const { + return (m_Weather == wStorm) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))) + } /** Returns true if the current weather has any precipitation - rain or storm */ bool IsWeatherWet (void) const { return (m_Weather != wSunny); } - + bool IsWeatherWet (int a_BlockX, int a_BlockZ) const { + return (m_Weather != wSunny) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))) + } // tolua_end cChunkGenerator & GetGenerator(void) { return m_Generator; } From c5010ebcc13c29a567755d938dabfa5250de73fc Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 11 Jun 2014 13:01:52 +0100 Subject: [PATCH 289/312] Add DoxyComments to he weather things. Also changed the function names. --- src/World.h | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/World.h b/src/World.h index b0fed84ba..ac275b991 100644 --- a/src/World.h +++ b/src/World.h @@ -707,22 +707,39 @@ 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 IsWeatherSunny(int a_BlockX, int a_BlockZ) const { + + /** Returns true if it is sunny at the specified location. This takes into accunt biomes. */ + bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const + { return (m_Weather == wSunny) } - bool IsWeatherRain (void) const { return (m_Weather == wRain); } - bool IsWeatherRain (int a_BlockX, int a_BlockZ) const { + + /** 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 accunt biomes. */ + bool IsWeatherRainAt (int a_BlockX, int a_BlockZ) const + { return (m_Weather == wRain) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))) } + + /** Returns true if the current weather is stormy */ bool IsWeatherStorm(void) const { return (m_Weather == wStorm); } - bool IsWeatherStorm(int a_BlockX, int a_BlockZ) const { + + /** Returns true if the weather is stormy at the specified location. This takes into accunt biomes. */ + bool IsWeatherStormAt(int a_BlockX, int a_BlockZ) const + { return (m_Weather == wStorm) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))) } - /** Returns true if the current weather has any precipitation - rain or storm */ - bool IsWeatherWet (void) const { return (m_Weather != wSunny); } - bool IsWeatherWet (int a_BlockX, int a_BlockZ) const { + /** Returns true if the current weather has any precipitation - rain, storm or snow */ + bool IsWeatherWet(void) const { return (m_Weather != wSunny); } + + /** Returns true if it is raining, stormy or snowing at the specified location. This takes into accunt biomes. */ + bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) const + { return (m_Weather != wSunny) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))) } // tolua_end From 711113cd2b9deaa2f556c446885e976a79fadcbf Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 11 Jun 2014 13:10:10 +0100 Subject: [PATCH 290/312] Updated unnecessary function :/ --- src/World.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/World.h b/src/World.h index ac275b991..11c262e3a 100644 --- a/src/World.h +++ b/src/World.h @@ -710,9 +710,13 @@ public: /** Returns true if the current weather is sun */ bool IsWeatherSunny(void) const { return (m_Weather == wSunny); } - /** Returns true if it is sunny at the specified location. This takes into accunt biomes. */ + /** Returns true if it is sunny at the specified location. This takes into accunt biomes. + This function is identical to IsWeatherSunny except for two extra parameters that aren't used, but bearbin insists :/ + */ bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const { + UNUSED(a_BlockX); + UNUSED(a_BlockZ); return (m_Weather == wSunny) } From 7e4abcfe2d2b1b5d5f73ebb990b24427323624e8 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 11 Jun 2014 14:14:54 +0200 Subject: [PATCH 291/312] Revert "Initial Mesa Bryce implementation." This reverts commit 1ff1a93866ab81e3868588a256f446a902a1a8c4. --- src/Generating/DistortedHeightmap.cpp | 4 +- src/Generating/DistortedHeightmap.h | 6 +- src/Generating/HeiGen.cpp | 89 --------------------------- src/Generating/HeiGen.h | 21 ------- 4 files changed, 4 insertions(+), 116 deletions(-) diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp index e50f36d57..eb9fe92ba 100644 --- a/src/Generating/DistortedHeightmap.cpp +++ b/src/Generating/DistortedHeightmap.cpp @@ -282,7 +282,7 @@ cDistortedHeightmap::cDistortedHeightmap(int a_Seed, cBiomeGen & a_BiomeGen) : m_OceanFloorSelect(a_Seed + 3000), m_MesaFloor(a_Seed + 4000), m_BiomeGen(a_BiomeGen), - m_UnderlyingHeiGen(a_Seed), + m_UnderlyingHeiGen(a_Seed, a_BiomeGen), m_HeightGen(m_UnderlyingHeiGen, 64), m_IsInitialized(false) { @@ -308,8 +308,6 @@ void cDistortedHeightmap::Initialize(cIniFile & a_IniFile) return; } - ((cTerrainHeightGen &)m_UnderlyingHeiGen).InitializeHeightGen(a_IniFile); - // Read the params from the INI file: m_SeaLevel = a_IniFile.GetValueSetI("Generator", "DistortedHeightmapSeaLevel", 62); m_FrequencyX = (NOISE_DATATYPE)a_IniFile.GetValueSetF("Generator", "DistortedHeightmapFrequencyX", 10); diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h index 31fb17df2..e6b3c9d3f 100644 --- a/src/Generating/DistortedHeightmap.h +++ b/src/Generating/DistortedHeightmap.h @@ -64,9 +64,9 @@ protected: int m_CurChunkZ; NOISE_DATATYPE m_DistortedHeightmap[17 * 257 * 17]; - cBiomeGen & m_BiomeGen; - cHeiGenMesaBryce m_UnderlyingHeiGen; // This generator provides us with base heightmap (before distortion) - cHeiGenCache m_HeightGen; // Cache above m_UnderlyingHeiGen + cBiomeGen & m_BiomeGen; + cHeiGenBiomal m_UnderlyingHeiGen; // This generator provides us with base heightmap (before distortion) + cHeiGenCache m_HeightGen; // Cache above m_UnderlyingHeiGen /// Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. cChunkDef::HeightMap m_CurChunkHeights; diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index dedf3fe3f..25ac912fd 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -47,10 +47,6 @@ cTerrainHeightGen * cTerrainHeightGen::CreateHeightGen(cIniFile &a_IniFile, cBio { res = new cEndGen(a_Seed); } - else if (NoCaseCompare(HeightGenName, "MesaBryce") == 0) - { - res = new cHeiGenMesaBryce(a_Seed); - } else if (NoCaseCompare(HeightGenName, "Mountains") == 0) { res = new cHeiGenMountains(a_Seed); @@ -370,91 +366,6 @@ void cHeiGenMountains::InitializeHeightGen(cIniFile & a_IniFile) -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cHeiGenMesaBryce: - -cHeiGenMesaBryce::cHeiGenMesaBryce(int a_Seed) : - m_Seed(a_Seed), - m_PerlinHFHA(a_Seed), - m_PerlinLFLA(a_Seed + 10) -{ -} - - - - - -void cHeiGenMesaBryce::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 Noise1[16 * 16]; - NOISE_DATATYPE Noise2[16 * 16]; - NOISE_DATATYPE Noise3[16 * 16]; - m_PerlinHFHA.Generate2D(Noise1, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); - m_PerlinLFLA.Generate2D(Noise2, 16, 16, StartX, EndX, StartZ, EndZ, Workspace); - m_PerlinTops.Generate2D(Noise3, 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 = 70 + (int)(std::min(Noise1[idx], Noise2[idx]) * 15); - int hei; - if (Noise1[idx] > 1.5f) - { - hei = 83 + (int)floor(Noise3[idx]); - } - else - { - hei = 63 + (int)floor(Noise2[idx]); - } - /* - NOISE_DATATYPE v1 = sqrt(sqrt(std::max(Noise1[idx], (NOISE_DATATYPE)0))) - 50; - int hei = 60 + (int)floor(std::max(v1, 5 + Noise2[idx])); - */ - if (hei < 10) - { - hei = 10; - } - if (hei > 250) - { - hei = 250; - } - cChunkDef::SetHeight(a_HeightMap, x , z, hei); - } // for x - } // for z -} - - - - - -void cHeiGenMesaBryce::InitializeHeightGen(cIniFile & a_IniFile) -{ - // TODO: Read the params from an INI file - // m_PerlinHFHA.AddOctave(0.32f, 0.1); - /* - m_PerlinHFHA.AddOctave(0.13f, 17800000); - m_PerlinHFHA.AddOctave(0.12f, 19000000); - */ - m_PerlinHFHA.AddOctave(0.13f, 2); - m_PerlinHFHA.AddOctave(0.12f, 2); - - m_PerlinLFLA.AddOctave(0.04f, 1); - m_PerlinLFLA.AddOctave(0.02f, 2); - - m_PerlinTops.AddOctave(0.1f, 8); -} - - - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cHeiGenBiomal: diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index 5fc4f4abc..5c106c7d9 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -127,27 +127,6 @@ protected: -class cHeiGenMesaBryce : - public cTerrainHeightGen -{ -public: - cHeiGenMesaBryce(int a_Seed); - -protected: - int m_Seed; - cPerlinNoise m_PerlinHFHA; // HighFrequencyHighAmplitude, for the hills - cPerlinNoise m_PerlinLFLA; // LowFrequencyLowAmplitude, for the floor - cPerlinNoise m_PerlinTops; - - // 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 { From c09207cabcecb94b134f92e2dbfdad69da930b43 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 11 Jun 2014 13:20:31 +0100 Subject: [PATCH 292/312] SMICOLOSL Meant to be semicolons up there. --- src/World.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/World.h b/src/World.h index 11c262e3a..a72904f6a 100644 --- a/src/World.h +++ b/src/World.h @@ -717,7 +717,7 @@ public: { UNUSED(a_BlockX); UNUSED(a_BlockZ); - return (m_Weather == wSunny) + return (m_Weather == wSunny); } /** Returns true if the current weather is rain */ @@ -726,7 +726,7 @@ public: /** Returns true if it is raining at the specified location. This takes into accunt biomes. */ bool IsWeatherRainAt (int a_BlockX, int a_BlockZ) const { - return (m_Weather == wRain) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))) + return (m_Weather == wRain) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } /** Returns true if the current weather is stormy */ @@ -735,7 +735,7 @@ public: /** Returns true if the weather is stormy at the specified location. This takes into accunt biomes. */ bool IsWeatherStormAt(int a_BlockX, int a_BlockZ) const { - return (m_Weather == wStorm) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))) + return (m_Weather == wStorm) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } /** Returns true if the current weather has any precipitation - rain, storm or snow */ @@ -744,7 +744,7 @@ public: /** Returns true if it is raining, stormy or snowing at the specified location. This takes into accunt biomes. */ bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) const { - return (m_Weather != wSunny) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))) + return (m_Weather != wSunny) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } // tolua_end From bd25069c25574f96ebf02de7360131bfe3504f04 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 11 Jun 2014 13:21:57 +0100 Subject: [PATCH 293/312] Update APIDesc.lua --- MCServer/Plugins/APIDump/APIDesc.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 40bfe79ac..1f43a6172 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2294,10 +2294,13 @@ 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)." }, + 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." }, From b3300e3854861d6957f5dac30ce0c7b027a3e2ad Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 11 Jun 2014 14:22:27 +0200 Subject: [PATCH 294/312] Added cBlockArea:GetCoordRange to Lua API. --- src/Bindings/ManualBindings.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 14d9d16fc..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 @@ -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); From 97bfccfdc0088705a4546d7d6369f3801946c1ba Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 11 Jun 2014 14:34:47 +0200 Subject: [PATCH 295/312] APIDump: Documented cBlockArea:GetCoordRange(). --- MCServer/Plugins/APIDump/APIDesc.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 40bfe79ac..800d1170e 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" }, From c335b8d77346541799b9c62e4fc78ef217cc4f63 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 11 Jun 2014 13:34:49 +0100 Subject: [PATCH 296/312] Update APIDesc.lua --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index 1f43a6172..8442f6d80 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2299,6 +2299,7 @@ end 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." }, + 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." }, From f7913d3b742e13595e3ded99820a13ade8a3b674 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 11 Jun 2014 13:37:04 +0100 Subject: [PATCH 297/312] IsWeatherSunnyAt does something useful :D --- src/World.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/World.h b/src/World.h index a72904f6a..f9471e881 100644 --- a/src/World.h +++ b/src/World.h @@ -710,20 +710,16 @@ public: /** Returns true if the current weather is sun */ bool IsWeatherSunny(void) const { return (m_Weather == wSunny); } - /** Returns true if it is sunny at the specified location. This takes into accunt biomes. - This function is identical to IsWeatherSunny except for two extra parameters that aren't used, but bearbin insists :/ - */ + /** Returns true if it is sunny at the specified location. This takes into account biomes. */ bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const { - UNUSED(a_BlockX); - UNUSED(a_BlockZ); - return (m_Weather == wSunny); + 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 accunt biomes. */ + /** Returns true if it is raining at the specified location. This takes into account biomes. */ bool IsWeatherRainAt (int a_BlockX, int a_BlockZ) const { return (m_Weather == wRain) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); @@ -732,7 +728,7 @@ public: /** Returns true if the current weather is stormy */ bool IsWeatherStorm(void) const { return (m_Weather == wStorm); } - /** Returns true if the weather is stormy at the specified location. This takes into accunt biomes. */ + /** Returns true if the weather is stormy at the specified location. This takes into account biomes. */ bool IsWeatherStormAt(int a_BlockX, int a_BlockZ) const { return (m_Weather == wStorm) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); @@ -741,7 +737,7 @@ public: /** Returns true if the current weather has any precipitation - rain, storm or snow */ bool IsWeatherWet(void) const { return (m_Weather != wSunny); } - /** Returns true if it is raining, stormy or snowing at the specified location. This takes into accunt biomes. */ + /** 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) const { return (m_Weather != wSunny) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); From 1a9467574e462f467dc9e1a9cc45b68c87276968 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 11 Jun 2014 13:40:34 +0100 Subject: [PATCH 298/312] Reduced code duplication call @maxmaxoft! calling... call connected (0:20) call ended --- src/World.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/World.h b/src/World.h index f9471e881..7469c1054 100644 --- a/src/World.h +++ b/src/World.h @@ -722,7 +722,7 @@ public: /** Returns true if it is raining at the specified location. This takes into account biomes. */ bool IsWeatherRainAt (int a_BlockX, int a_BlockZ) const { - return (m_Weather == wRain) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); + return (IsWeatherRain() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } /** Returns true if the current weather is stormy */ @@ -731,16 +731,16 @@ public: /** Returns true if the weather is stormy at the specified location. This takes into account biomes. */ bool IsWeatherStormAt(int a_BlockX, int a_BlockZ) const { - return (m_Weather == wStorm) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, 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 (m_Weather != wSunny); } + 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) const { - return (m_Weather != wSunny) && (!IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); + return (IsWeatherWet() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } // tolua_end From e24830f0b12597896d895855298e8dde5f448b5b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 11 Jun 2014 13:49:57 +0100 Subject: [PATCH 299/312] Compile fix --- src/World.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/World.h b/src/World.h index 7469c1054..45b42b280 100644 --- a/src/World.h +++ b/src/World.h @@ -597,7 +597,7 @@ public: void GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); /** Returns the biome at the specified coords. Reads the biome from the chunk, if loaded, otherwise uses the world generator to provide the biome value */ - EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ); + EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ) const; /** Sets the biome at the specified coords. Returns true if successful, false if not (chunk not loaded). Doesn't resend the chunk to clients, use ForceSendChunkTo() for that. */ From 70c20d77721f69e9f04a27630a4e4b65c5be601f Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 11 Jun 2014 16:23:53 +0100 Subject: [PATCH 300/312] Fixed constness --- lib/tolua++/src/bin/basic_lua.h | 139 ++++++++++++++------------ lib/tolua++/src/bin/declaration_lua.h | 2 +- src/World.h | 10 +- 3 files changed, 79 insertions(+), 72 deletions(-) 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/src/World.h b/src/World.h index 45b42b280..0a8dcffc4 100644 --- a/src/World.h +++ b/src/World.h @@ -597,7 +597,7 @@ public: void GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); /** Returns the biome at the specified coords. Reads the biome from the chunk, if loaded, otherwise uses the world generator to provide the biome value */ - EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ) const; + EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ); /** Sets the biome at the specified coords. Returns true if successful, false if not (chunk not loaded). Doesn't resend the chunk to clients, use ForceSendChunkTo() for that. */ @@ -711,7 +711,7 @@ public: bool IsWeatherSunny(void) const { return (m_Weather == wSunny); } /** Returns true if it is sunny at the specified location. This takes into account biomes. */ - bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) const + bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) { return (IsWeatherSunny() || IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } @@ -720,7 +720,7 @@ public: 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) const + bool IsWeatherRainAt (int a_BlockX, int a_BlockZ) { return (IsWeatherRain() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } @@ -729,7 +729,7 @@ public: bool IsWeatherStorm(void) const { return (m_Weather == wStorm); } /** Returns true if the weather is stormy at the specified location. This takes into account biomes. */ - bool IsWeatherStormAt(int a_BlockX, int a_BlockZ) const + bool IsWeatherStormAt(int a_BlockX, int a_BlockZ) { return (IsWeatherStorm() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } @@ -738,7 +738,7 @@ public: 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) const + bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) { return (IsWeatherWet() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } From f9fd5193602f4cbf0b201e13e9b410b264d09bf2 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Wed, 11 Jun 2014 17:26:10 +0100 Subject: [PATCH 301/312] Changed the teleport permissions to the new ones. --- src/GroupManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); From 7cf544079f910ac8068b67ad39178ad040816367 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 11 Jun 2014 19:12:29 +0200 Subject: [PATCH 302/312] Roads in villages are made out of wooden planks if they generate on water. --- src/Generating/VillageGen.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index b9cb056ad..9917141ed 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -116,7 +116,8 @@ public: int a_Density, cPiecePool & a_Prefabs, cTerrainHeightGen & a_HeightGen, - BLOCKTYPE a_RoadBlock + BLOCKTYPE a_RoadBlock, + BLOCKTYPE a_WaterRoadBlock ) : super(a_OriginX, a_OriginZ), m_Seed(a_Seed), @@ -126,7 +127,8 @@ public: 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_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); @@ -179,6 +181,9 @@ protected: /** 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: @@ -239,7 +244,14 @@ protected: { for (int x = MinX; x <= MaxX; x++) { - a_Chunk.SetBlockType(x, cChunkDef::GetHeight(a_HeightMap, x, z), z, m_RoadBlock); + 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); + } } } } @@ -374,6 +386,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ // 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)]; @@ -422,7 +435,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_OriginX, int a_ { return cStructurePtr(); } - return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *VillagePrefabs, m_HeightGen, RoadBlock)); + return cStructurePtr(new cVillage(m_Seed, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *VillagePrefabs, m_HeightGen, RoadBlock, WaterRoadBlock)); } From 220e6f5880354c9984e18718f723331bb904df45 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 11 Jun 2014 19:46:24 +0200 Subject: [PATCH 303/312] DispenserEntity code cleanup after PR merge. --- src/BlockEntities/DispenserEntity.cpp | 41 ++++++++++++--------------- src/BlockEntities/DispenserEntity.h | 19 ++++++++----- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/BlockEntities/DispenserEntity.cpp b/src/BlockEntities/DispenserEntity.cpp index 97e25ca6d..c02c68afa 100644 --- a/src/BlockEntities/DispenserEntity.cpp +++ b/src/BlockEntities/DispenserEntity.cpp @@ -150,31 +150,27 @@ void cDispenserEntity::DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) { 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); + 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); + 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); + SpawnProjectileFromDispenser(BlockX, DispY, BlockZ, cProjectileEntity::pkEgg, GetShootVector(Meta) * 20 + Vector3d(0, 1, 0)); m_Contents.ChangeSlotCount(a_SlotNum, -1); - break; } @@ -194,31 +190,30 @@ 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, Vector3d a_ShootVector) -{ - if (a_Kind != cProjectileEntity::pkFireCharge) - { - a_ShootVector.y = a_ShootVector.y + 1; - } - m_World->CreateProjectile((double) a_BlockX + 0.5, (double) a_BlockY + 0.5, (double) a_BlockZ + 0.5, a_Kind, NULL, NULL, &a_ShootVector); + +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) + + + +Vector3d cDispenserEntity::GetShootVector(NIBBLETYPE a_Meta) { - switch(a_Meta) + switch (a_Meta) { - case E_META_DROPSPENSER_FACING_YP: return Vector3d( 0, 1, 0); // UP - case E_META_DROPSPENSER_FACING_YM: return Vector3d( 0, -1, 0); // DOWN - - case E_META_DROPSPENSER_FACING_XM: return Vector3d(-1, 0, 0); // WEST - case E_META_DROPSPENSER_FACING_XP: return Vector3d( 1, 0, 0); // EAST - + 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); } diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index 9410a1129..b33d08342 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -17,25 +17,30 @@ 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"; } - /** Spawns a projectile of the given kind in front of the dispenser */ - void SpawnProjectileFromDispenser(int & a_BlockX, int & a_BlockY, int & a_BlockZ, cProjectileEntity::eKind a_Kind, Vector3d a_ShootVector); + // 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 how to aim the projectile */ - Vector3d GetShootVector(NIBBLETYPE & a_Meta); + /** 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 From 3e7384d9210b726a12ec6244aa0419474f08c6d3 Mon Sep 17 00:00:00 2001 From: Qais Patankar Date: Thu, 12 Jun 2014 15:01:24 +0100 Subject: [PATCH 304/312] Fix typo in handy_functions.lua --- MCServer/Plugins/Handy/handy_functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From 1bce1ac4327965453d7709503c5f0b4d8b3edea6 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 12 Jun 2014 17:13:39 +0100 Subject: [PATCH 305/312] Fixed two redstone bugs * Fixed chunk border powering * Fixed quick place-replace powering --- src/Simulator/IncrementalRedstoneSimulator.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index b32a57165..eff11bd01 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -65,6 +65,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, 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); + a_OtherChunk->SetIsRedstoneDirty(true); } else { @@ -199,6 +200,7 @@ void cIncrementalRedstoneSimulator::RedstoneAddBlock(int a_BlockX, int a_BlockY, } else { + itr->DataTwo = false; itr->Data = Block; // Update block information } return; @@ -802,11 +804,15 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int { if (a_Itr->a_RelBlockPos == Vector3i(a_RelBlockX, a_RelBlockY, a_RelBlockZ)) { + // Leave a_Itr at where we found the entry break; } } } + // a_Itr may be passed with m_RepeatersDelayList::end, however, we can guarantee this iterator is always valid because... + // ...QueueRepeaterPowerChange is called to add an entry (and the above code updates iterator). However, if the repeater was locked or something similar... + // ...we will never get here because of the returns. if (a_Itr->a_ElapsedTicks >= a_Itr->a_DelayTicks) // Has the elapsed ticks reached the target ticks? { if (a_Itr->ShouldPowerOn) From 9254666a85f9e4562081bea336c8be0e612fa44d Mon Sep 17 00:00:00 2001 From: tycho Date: Thu, 12 Jun 2014 18:00:53 +0100 Subject: [PATCH 306/312] automaticlly build tolua and generate bindings as part of build. --- src/Bindings/tolua++.exe | Bin 200704 -> 0 bytes src/CMakeLists.txt | 169 ++++++++++++++++++++------------------- 2 files changed, 85 insertions(+), 84 deletions(-) delete mode 100644 src/Bindings/tolua++.exe diff --git a/src/Bindings/tolua++.exe b/src/Bindings/tolua++.exe deleted file mode 100644 index ba3a6b0c703968167e89e26e649c1dc33c49cdaa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 200704 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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 900577526..c5156e50c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,91 @@ 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 +) + +include_directories(Bindings) +include_directories(.) + +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 + 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} +) if (NOT MSVC) @@ -15,91 +100,7 @@ if (NOT MSVC) # 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 - ) - include_directories(Bindings) - include_directories(.) - - 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 - 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} - ) #add cpp files here add_library(Bindings Bindings/Bindings From 383c5c2c89661bfadab7c3b8bbfcf57401e952f2 Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Thu, 12 Jun 2014 19:31:16 +0100 Subject: [PATCH 307/312] Typo Correction --- GETTING-STARTED.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GETTING-STARTED.md b/GETTING-STARTED.md index eb7d1b713..d78b2f84f 100644 --- a/GETTING-STARTED.md +++ b/GETTING-STARTED.md @@ -3,7 +3,7 @@ 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. It is possabile to contribute without knowing minecraft in detail though. +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: From 72043f5b0cc2e930c2a616d84a8fea25f7224c59 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 13 Jun 2014 00:09:01 +0200 Subject: [PATCH 308/312] APIDump: Added the Info.lua article. Fixes #504. --- MCServer/Plugins/APIDump/APIDesc.lua | 1 + MCServer/Plugins/APIDump/InfoFile.html | 246 +++++++++++++++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 MCServer/Plugins/APIDump/InfoFile.html diff --git a/MCServer/Plugins/APIDump/APIDesc.lua b/MCServer/Plugins/APIDump/APIDesc.lua index c97e2dbf8..19ca971e2 100644 --- a/MCServer/Plugins/APIDump/APIDesc.lua +++ b/MCServer/Plugins/APIDump/APIDesc.lua @@ -2934,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/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 @@ + + + + MCServer - Info.lua file + + + + + + + +

    +

    Info.lua file

    +

    Contents

    +
    + + +
    +

    Introduction

    + +

    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.

    + +

    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 & 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.

    + +

    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.

    + +

    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.

    + +

    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.

    + + +
    +

    The overall structure

    + +

    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.

    +

    Here's a skeleton of the file:

    +
    +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 = {},
    +}
    +
    +

    As you can see, the structure is pretty straightforward. Note that the order of the elements inside the table is not important (Lua property).

    + +

    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.

    + + +
    +

    AdditionalInformation table

    + +

    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.

    + +

    The table should have the following layout:

    +
    +AdditionalInformation =
    +{
    +	{
    +		Title = "Chapter 1",
    +		Contents = "Describe one big aspect of the plugin here",
    +	},
    +	{
    +		Title = "Chapter 2",
    +		Contents = "Describe another big topic",
    +	},
    +}
    +
    +

    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.

    + + +
    +

    Commands table

    + +

    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.

    + +

    The table uses structure similar to the following:

    +
    +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,
    +			},
    +		},
    +	},
    +}
    +
    + +

    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 (["/cmd1"] =). 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.

    + +

    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.

    + +

    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.

    + +

    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.

    + + +
    +

    ConsoleCommands table

    + +

    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.

    + +

    Here's an example of a ConsoleCommands table:

    +
    +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,
    +			},
    +		},
    +	},
    +}
    +
    + + +
    +

    Permissions table

    + +

    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.

    + +
    +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",
    +	},
    +}
    +
    + +

    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.

    + + +
    +

    Using the file in code

    + +

    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:

    +
    +-- Use the InfoReg shared library to process the Info.lua file:
    +dofile(cPluginManager:GetPluginsPath() .. "/InfoReg.lua")
    +RegisterPluginInfoCommands()
    +RegisterPluginInfoConsoleCommands()
    +
    + +

    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.

    + + +
    +

    Examples

    + +

    There are several plugins that already implement this approach. You can visit them for inspiration and to see what the generated documentation looks like:

    + + + +
    + + From f76420ac55edd82e06042a93927e275e5799d59f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 13 Jun 2014 09:38:25 +0200 Subject: [PATCH 309/312] Removed an unused fwd declaration. --- src/World.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/World.h b/src/World.h index 0a8dcffc4..3e63e2b8c 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; From b0f1707d50895d47634095592f68da63621f6507 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Fri, 13 Jun 2014 23:16:52 +0200 Subject: [PATCH 310/312] Fixed ChunkWorx stop button giving an error --- MCServer/Plugins/ChunkWorx/chunkworx_web.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 4b28a24514316f04d596e248a75b382701a01217 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 14 Jun 2014 09:51:42 +0100 Subject: [PATCH 311/312] Reduced cPluginManager code duplication --- src/Bindings/PluginManager.cpp | 464 +++++++++++++-------------------- 1 file changed, 178 insertions(+), 286 deletions(-) diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index acfc91bf8..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)) @@ -1157,11 +1075,9 @@ bool cPluginManager::CallHookPreCrafting(const cPlayer * a_Player, const cCrafti 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, a_BlockX, a_BlockY, a_BlockZ, a_Face, a_BlockHitPos)) @@ -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)) From c1deda5d8f01811efa5094e9375166acb69d50ed Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 14 Jun 2014 10:47:10 +0100 Subject: [PATCH 312/312] Fixed a repeater issue * Repeaters now properly continuously update their powering * Minor cosmetic improvements --- .../IncrementalRedstoneSimulator.cpp | 31 +++++++++---------- src/Simulator/IncrementalRedstoneSimulator.h | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Simulator/IncrementalRedstoneSimulator.cpp b/src/Simulator/IncrementalRedstoneSimulator.cpp index eff11bd01..f20f396f2 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.cpp +++ b/src/Simulator/IncrementalRedstoneSimulator.cpp @@ -788,12 +788,12 @@ void cIncrementalRedstoneSimulator::HandleRedstoneRepeater(int a_RelBlockX, int { WereItrsChanged = QueueRepeaterPowerChange(a_RelBlockX, a_RelBlockY, a_RelBlockZ, a_Meta, false); } - else + else if (a_Itr != m_RepeatersDelayList->end()) { return; } } - else + else if (a_Itr != m_RepeatersDelayList->end()) { return; } @@ -1429,8 +1429,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 @@ -1510,19 +1509,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; @@ -1532,26 +1531,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 } @@ -1610,7 +1609,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 @@ -1619,10 +1618,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? } diff --git a/src/Simulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator.h index 83076311a..1d6a49aca 100644 --- a/src/Simulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator.h @@ -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);