From 8090c13cde2d61a0330f1e262de7526318a0965d Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Fri, 15 Mar 2013 20:18:11 +0000 Subject: Huge performance boost in blockhandlers, they have direct access to chunk data when blockchecking. Also fixed vines' placement. git-svn-id: http://mc-server.googlecode.com/svn/trunk@1278 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Blocks/BlockCactus.h | 37 ++++-- source/Blocks/BlockCrops.h | 4 +- source/Blocks/BlockDoor.h | 4 +- source/Blocks/BlockFlower.h | 4 +- source/Blocks/BlockFluid.h | 8 +- source/Blocks/BlockHandler.cpp | 25 ++-- source/Blocks/BlockHandler.h | 9 +- source/Blocks/BlockLadder.h | 19 +-- source/Blocks/BlockMushroom.h | 11 +- source/Blocks/BlockRail.h | 212 +++++++++++++++++++++++----------- source/Blocks/BlockRedstone.h | 4 +- source/Blocks/BlockRedstoneRepeater.h | 4 +- source/Blocks/BlockSapling.h | 4 +- source/Blocks/BlockSnow.h | 5 +- source/Blocks/BlockStems.h | 4 +- source/Blocks/BlockSugarcane.h | 36 +++++- source/Blocks/BlockTallGrass.h | 4 +- source/Blocks/BlockTorch.h | 11 +- source/Blocks/BlockVine.h | 105 ++++++++++++----- source/Chunk.cpp | 36 ++++-- source/Chunk.h | 29 ++--- source/Vine.h | 69 +++++------ 22 files changed, 418 insertions(+), 226 deletions(-) (limited to 'source') diff --git a/source/Blocks/BlockCactus.h b/source/Blocks/BlockCactus.h index daa0e02c2..516f024d8 100644 --- a/source/Blocks/BlockCactus.h +++ b/source/Blocks/BlockCactus.h @@ -24,9 +24,13 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - BLOCKTYPE Surface = a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); + if (a_RelY <= 0) + { + return false; + } + BLOCKTYPE Surface = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); if ((Surface != E_BLOCK_SAND) && (Surface != E_BLOCK_CACTUS)) { // Cactus can only be placed on sand and itself @@ -34,15 +38,28 @@ public: } // Check surroundings. Cacti may ONLY be surrounded by air - if ( - (a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) || - (a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ) != E_BLOCK_AIR) || - (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1) != E_BLOCK_AIR) || - (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1) != E_BLOCK_AIR) - ) + static const struct { - return false; - } + int x, z; + } Coords[] = + { + {-1, 0}, + { 1, 0}, + { 0, -1}, + { 0, 1}, + } ; + for (int i = 0; i < ARRAYCOUNT(Coords); i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if ( + a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) && + (BlockType != E_BLOCK_AIR) + ) + { + return false; + } + } // for i - Coords[] return true; } diff --git a/source/Blocks/BlockCrops.h b/source/Blocks/BlockCrops.h index 0a8017a91..a269c7c32 100644 --- a/source/Blocks/BlockCrops.h +++ b/source/Blocks/BlockCrops.h @@ -44,9 +44,9 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) == E_BLOCK_FARMLAND; + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_FARMLAND)); } diff --git a/source/Blocks/BlockDoor.h b/source/Blocks/BlockDoor.h index 0e4a5ff52..a988c2d4b 100644 --- a/source/Blocks/BlockDoor.h +++ b/source/Blocks/BlockDoor.h @@ -74,9 +74,9 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return (a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_AIR); + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); } diff --git a/source/Blocks/BlockFlower.h b/source/Blocks/BlockFlower.h index 7db42c9fc..b46273c51 100644 --- a/source/Blocks/BlockFlower.h +++ b/source/Blocks/BlockFlower.h @@ -24,9 +24,9 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return IsBlockTypeOfDirt(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)); + return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)); } diff --git a/source/Blocks/BlockFluid.h b/source/Blocks/BlockFluid.h index a8cd9c497..b184a5b33 100644 --- a/source/Blocks/BlockFluid.h +++ b/source/Blocks/BlockFluid.h @@ -26,22 +26,22 @@ public: } - virtual void Check(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override { switch (m_BlockType) { case E_BLOCK_STATIONARY_LAVA: { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_LAVA, a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)); + a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_LAVA, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); break; } case E_BLOCK_STATIONARY_WATER: { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_WATER, a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)); + a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_WATER, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); break; } } - super::Check(a_World, a_BlockX, a_BlockY, a_BlockZ); + super::Check(a_RelX, a_RelY, a_RelZ, a_Chunk); } } ; diff --git a/source/Blocks/BlockHandler.cpp b/source/Blocks/BlockHandler.cpp index 71d56f94d..991102aca 100644 --- a/source/Blocks/BlockHandler.cpp +++ b/source/Blocks/BlockHandler.cpp @@ -351,16 +351,7 @@ const char * cBlockHandler::GetStepSound() -bool cBlockHandler::CanBePlacedAt(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir) -{ - return CanBeAt(a_World, a_BlockX, a_BlockY, a_BlockZ); -} - - - - - -bool cBlockHandler::CanBeAt(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +bool cBlockHandler::CanBeAt(int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk) { return true; } @@ -423,21 +414,25 @@ bool cBlockHandler::DoesDropOnUnsuitable(void) -void cBlockHandler::Check(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) +void cBlockHandler::Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) { - if (!CanBeAt(a_World, a_BlockX, a_BlockY, a_BlockZ)) + if (!CanBeAt(a_RelX, a_RelY, a_RelZ, a_Chunk)) { if (DoesDropOnUnsuitable()) { - DropBlock(a_World, NULL, a_BlockX, a_BlockY, a_BlockZ); + int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; + int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; + DropBlock(a_Chunk.GetWorld(), NULL, BlockX, a_RelY, BlockZ); } - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); + a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); } else { // Wake up the simulators for this block: - a_World->WakeUpSimulators(a_BlockX, a_BlockY, a_BlockZ); + int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; + int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; + a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, &a_Chunk); } } diff --git a/source/Blocks/BlockHandler.h b/source/Blocks/BlockHandler.h index e551668f9..4c91463bc 100644 --- a/source/Blocks/BlockHandler.h +++ b/source/Blocks/BlockHandler.h @@ -3,6 +3,7 @@ #include "../Defines.h" #include "../Item.h" +#include "../Chunk.h" @@ -74,14 +75,14 @@ public: /// Returns step sound name of block virtual const char * GetStepSound(void); - /// Checks if the block can stay at the specified coords in the world - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); + /// Checks if the block can stay at the specified relative coords in the chunk + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk); /** Checks if the block can be placed at this point. Default: CanBeAt(...) NOTE: This call doesn't actually place the block */ - virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); + // virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); /// Called when the player tries to place a block on top of this block (Only if he aims directly on this block); return false to disallow virtual bool DoesAllowBlockOnTop(void); @@ -109,7 +110,7 @@ public: By default drops if position no more suitable (CanBeAt(), DoesDropOnUnsuitable(), Drop()), and wakes up all simulators on the block. */ - virtual void Check(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); + virtual void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk); /// Get the blockhandler for a specific block id diff --git a/source/Blocks/BlockLadder.h b/source/Blocks/BlockLadder.h index 5f0b09737..280f0deb1 100644 --- a/source/Blocks/BlockLadder.h +++ b/source/Blocks/BlockLadder.h @@ -69,20 +69,13 @@ public: } - virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - if (LadderCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) - { - return true; - } - return (FindSuitableBlockFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM); - } - - - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - char BlockFace = cLadder::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)); - return CanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, BlockFace); + // TODO: Use cTorch::AdjustCoordsByMeta(), then cChunk::UnboundedRelGetBlock() and finally some comparison + char BlockFace = cLadder::MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; + int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; + return LadderCanBePlacedAt(a_Chunk.GetWorld(), BlockX, a_RelY, BlockZ, BlockFace); } diff --git a/source/Blocks/BlockMushroom.h b/source/Blocks/BlockMushroom.h index 96bdbc310..62cc898c0 100644 --- a/source/Blocks/BlockMushroom.h +++ b/source/Blocks/BlockMushroom.h @@ -24,9 +24,16 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - switch (a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)) + if (a_RelY <= 0) + { + return false; + } + + // TODO: Cannot be at too much daylight + + switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) { case E_BLOCK_GLASS: case E_BLOCK_CACTUS: diff --git a/source/Blocks/BlockRail.h b/source/Blocks/BlockRail.h index 733f92c8c..60865abf5 100644 --- a/source/Blocks/BlockRail.h +++ b/source/Blocks/BlockRail.h @@ -8,19 +8,36 @@ +/// Meta values for the rail enum ENUM_RAIL_DIRECTIONS { - E_RAIL_NORTH_SOUTH = 0, - E_RAIL_EAST_WEST = 1, - E_RAIL_ASCEND_EAST = 2, - E_RAIL_ASCEND_WEST = 3, - E_RAIL_ASCEND_NORTH = 4, - E_RAIL_ASCEND_SOUTH = 5, + E_RAIL_NORTH_SOUTH = 0, + E_RAIL_EAST_WEST = 1, + E_RAIL_ASCEND_EAST = 2, + E_RAIL_ASCEND_WEST = 3, + E_RAIL_ASCEND_NORTH = 4, + E_RAIL_ASCEND_SOUTH = 5, E_RAIL_CURVED_SOUTH_EAST = 6, E_RAIL_CURVED_SOUTH_WEST = 7, E_RAIL_CURVED_NORTH_WEST = 8, - E_RAIL_CURVED_NORTH_EAST = 9 -}; + E_RAIL_CURVED_NORTH_EAST = 9, + + // Some useful synonyms: + E_RAIL_DIR_X = E_RAIL_EAST_WEST, + E_RAIL_DIR_Z = E_RAIL_NORTH_SOUTH, + E_RAIL_ASCEND_XP = E_RAIL_ASCEND_EAST, + E_RAIL_ASCEND_XM = E_RAIL_ASCEND_WEST, + E_RAIL_ASCEND_ZM = E_RAIL_ASCEND_NORTH, + E_RAIL_ASCEND_ZP = E_RAIL_ASCEND_SOUTH, + E_RAIL_CURVED_XPZP = E_RAIL_CURVED_SOUTH_EAST, + E_RAIL_CURVED_XMZP = E_RAIL_CURVED_SOUTH_WEST, + E_RAIL_CURVED_XMZM = E_RAIL_CURVED_NORTH_WEST, + E_RAIL_CURVED_XPZM = E_RAIL_CURVED_NORTH_EAST, +} ; + + + + enum ENUM_PURE { @@ -65,46 +82,45 @@ public: } - virtual bool CanBeAt(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]) + if (a_RelY <= 0) { return false; } - NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + if (!g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]) + { + return false; + } + + NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); switch (Meta) { case E_RAIL_ASCEND_EAST: - { - if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX + 1, a_BlockY, a_BlockZ)]) - { - return false; - } - break; - } case E_RAIL_ASCEND_WEST: - { - if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX - 1, a_BlockY, a_BlockZ)]) - { - return false; - } - break; - } case E_RAIL_ASCEND_NORTH: - { - if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ - 1)]) - { - return false; - } - break; - } case E_RAIL_ASCEND_SOUTH: { - if (!g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ + 1)]) + // Mapping between the meta and the neighbors that need checking + Meta -= E_RAIL_ASCEND_EAST; // Base index at zero + static const struct { - return false; + int x, z; + } Coords[] = + { + { 1, 0}, // east, XP + {-1, 0}, // west, XM + { 0, -1}, // north, ZM + { 0, 1}, // south, ZP + } ; + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if (!a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[Meta].x, a_RelY, a_RelZ + Coords[Meta].z, BlockType, BlockMeta)) + { + // Too close to the edge, cannot simulate + return true; } - break; + return g_BlockIsSolid[BlockType]; } } return true; @@ -159,16 +175,16 @@ public: } if (RailsCnt > 1) { - if (Neighbors[3] && Neighbors[0]) return E_RAIL_CURVED_SOUTH_EAST; - else if(Neighbors[3] && Neighbors[1]) return E_RAIL_CURVED_SOUTH_WEST; - else if(Neighbors[2] && Neighbors[0]) return E_RAIL_CURVED_NORTH_EAST; - else if(Neighbors[2] && Neighbors[1]) return E_RAIL_CURVED_NORTH_WEST; - else if(Neighbors[7] && Neighbors[2]) return E_RAIL_ASCEND_SOUTH; - else if(Neighbors[3] && Neighbors[6]) return E_RAIL_ASCEND_NORTH; - else if(Neighbors[5] && Neighbors[0]) return E_RAIL_ASCEND_WEST; - else if(Neighbors[4] && Neighbors[1]) return E_RAIL_ASCEND_EAST; - else if(Neighbors[0] && Neighbors[1]) return E_RAIL_EAST_WEST; - else if(Neighbors[2] && Neighbors[3]) return E_RAIL_NORTH_SOUTH; + if (Neighbors[3] && Neighbors[0]) return E_RAIL_CURVED_SOUTH_EAST; + else if (Neighbors[3] && Neighbors[1]) return E_RAIL_CURVED_SOUTH_WEST; + else if (Neighbors[2] && Neighbors[0]) return E_RAIL_CURVED_NORTH_EAST; + else if (Neighbors[2] && Neighbors[1]) return E_RAIL_CURVED_NORTH_WEST; + else if (Neighbors[7] && Neighbors[2]) return E_RAIL_ASCEND_SOUTH; + else if (Neighbors[3] && Neighbors[6]) return E_RAIL_ASCEND_NORTH; + else if (Neighbors[5] && Neighbors[0]) return E_RAIL_ASCEND_WEST; + else if (Neighbors[4] && Neighbors[1]) return E_RAIL_ASCEND_EAST; + else if (Neighbors[0] && Neighbors[1]) return E_RAIL_EAST_WEST; + else if (Neighbors[2] && Neighbors[3]) return E_RAIL_NORTH_SOUTH; ASSERT(!"Weird neighbor count"); } return Meta; @@ -177,68 +193,130 @@ public: bool IsUnstable(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) { - if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) return false; + if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) + { + return false; + } NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); switch (Meta) { case E_RAIL_NORTH_SOUTH: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN) || - IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN) || + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN) + ) + { + return true; + } break; } + case E_RAIL_EAST_WEST: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN) || - IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN) || + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN) + ) + { + return true; + } break; } + case E_RAIL_ASCEND_EAST: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST) || - IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST) || + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST) + ) + { + return true; + } break; } + case E_RAIL_ASCEND_WEST: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST) || - IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST) || + IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST) + ) + { + return true; + } break; } + case E_RAIL_ASCEND_NORTH: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH) || - IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH) || + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) + ) + { + return true; + } break; } + case E_RAIL_ASCEND_SOUTH: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) || - IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) || + IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH) + ) + { + return true; + } break; } + case E_RAIL_CURVED_SOUTH_EAST: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) || - IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) || + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST) + ) + { + return true; + } break; } + case E_RAIL_CURVED_SOUTH_WEST: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) || - IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) || + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST) + ) + { + return true; + } break; } + case E_RAIL_CURVED_NORTH_WEST: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) || - IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) || + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST) + ) + { + return true; + } break; } + case E_RAIL_CURVED_NORTH_EAST: { - if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) || - IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST)) return true; + if ( + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) || + IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST) + ) + { + return true; + } break; } } @@ -246,7 +324,7 @@ public: } - bool IsNotConnected(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Pure = 0) + bool IsNotConnected(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Pure = 0) { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); NIBBLETYPE Meta; diff --git a/source/Blocks/BlockRedstone.h b/source/Blocks/BlockRedstone.h index ce0ff64d5..3a4649d7e 100644 --- a/source/Blocks/BlockRedstone.h +++ b/source/Blocks/BlockRedstone.h @@ -22,9 +22,9 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return g_BlockIsSolid[a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)]; + return ((a_RelY > 0) && g_BlockIsSolid[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]); } diff --git a/source/Blocks/BlockRedstoneRepeater.h b/source/Blocks/BlockRedstoneRepeater.h index fbd415160..4a16149fd 100644 --- a/source/Blocks/BlockRedstoneRepeater.h +++ b/source/Blocks/BlockRedstoneRepeater.h @@ -38,9 +38,9 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_AIR; + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); } diff --git a/source/Blocks/BlockSapling.h b/source/Blocks/BlockSapling.h index 18fdb9d05..957331886 100644 --- a/source/Blocks/BlockSapling.h +++ b/source/Blocks/BlockSapling.h @@ -25,9 +25,9 @@ public: } - virtual bool CanBeAt(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return IsBlockTypeOfDirt(a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)); + return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)); } diff --git a/source/Blocks/BlockSnow.h b/source/Blocks/BlockSnow.h index 2a5009b69..f150f497c 100644 --- a/source/Blocks/BlockSnow.h +++ b/source/Blocks/BlockSnow.h @@ -29,10 +29,9 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - BLOCKTYPE UnderlyingBlock = a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ); - return g_BlockIsSnowable[UnderlyingBlock]; + return (a_RelY > 0) && g_BlockIsSnowable[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)]; } diff --git a/source/Blocks/BlockStems.h b/source/Blocks/BlockStems.h index ba93097f9..44c4d9cc9 100644 --- a/source/Blocks/BlockStems.h +++ b/source/Blocks/BlockStems.h @@ -41,9 +41,9 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) == E_BLOCK_FARMLAND; + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) == E_BLOCK_FARMLAND)); } diff --git a/source/Blocks/BlockSugarcane.h b/source/Blocks/BlockSugarcane.h index 9470900f0..a9503ba37 100644 --- a/source/Blocks/BlockSugarcane.h +++ b/source/Blocks/BlockSugarcane.h @@ -23,16 +23,46 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - switch (a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ)) + if (a_RelY <= 0) + { + return false; + } + switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) { case E_BLOCK_DIRT: case E_BLOCK_GRASS: case E_BLOCK_FARMLAND: case E_BLOCK_SAND: { - return a_World->IsBlockDirectlyWatered(a_BlockX, a_BlockY - 1, a_BlockZ); + static const struct + { + int x, z; + } Coords[] = + { + {-1, 0}, + { 1, 0}, + { 0, -1}, + { 0, 1}, + } ; + a_RelY -= 1; + for (int i = 0; i < ARRAYCOUNT(Coords); i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if (!a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta)) + { + // Too close to the edge, cannot simulate + return true; + } + if (IsBlockWater(BlockType)) + { + return true; + } + } // for i - Coords[] + // Not directly neighboring a water block + return false; } case E_BLOCK_SUGARCANE: { diff --git a/source/Blocks/BlockTallGrass.h b/source/Blocks/BlockTallGrass.h index 702ebf14c..eea629bf5 100644 --- a/source/Blocks/BlockTallGrass.h +++ b/source/Blocks/BlockTallGrass.h @@ -34,9 +34,9 @@ public: } - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_AIR; + return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); } diff --git a/source/Blocks/BlockTorch.h b/source/Blocks/BlockTorch.h index 43c5cdb4c..3cc487421 100644 --- a/source/Blocks/BlockTorch.h +++ b/source/Blocks/BlockTorch.h @@ -98,6 +98,7 @@ public: } + /* virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override { if (TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) @@ -107,12 +108,16 @@ public: return (FindSuitableFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM); } + */ - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - char Face = cTorch::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ)); - return TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Face); + // TODO: Use cTorch::AdjustCoordsByMeta(), then cChunk::UnboundedRelGetBlock() and finally some comparison + char Face = cTorch::MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); + int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; + int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; + return TorchCanBePlacedAt(a_Chunk.GetWorld(), BlockX, a_RelY, BlockZ, Face); } diff --git a/source/Blocks/BlockVine.h b/source/Blocks/BlockVine.h index 2f35c11d9..88338e86d 100644 --- a/source/Blocks/BlockVine.h +++ b/source/Blocks/BlockVine.h @@ -25,45 +25,98 @@ public: BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ) override { + // TODO: Disallow placement where the vine doesn't attach to something properly + BLOCKTYPE BlockType = 0; + NIBBLETYPE BlockMeta; + a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta); + if (BlockType == m_BlockType) + { + a_BlockMeta = BlockMeta | cVine::DirectionToMetaData(a_BlockFace); + } + else + { + a_BlockMeta = cVine::DirectionToMetaData(a_BlockFace); + } a_BlockType = m_BlockType; - a_BlockMeta = cVine::DirectionToMetaData(a_BlockFace); return true; } - virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override + /// Returns true if the specified block type is good for vines to attach to + static bool IsBlockAttachable(BLOCKTYPE a_BlockType) { - if ( - (a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ ) == E_BLOCK_VINES) && - (cVine::MetaDataToDirection(a_World->GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ)) == a_BlockFace) - ) + return (a_BlockType == E_BLOCK_LEAVES) || g_BlockIsSolid[a_BlockType]; + } + + + /// Returns the meta that has the maximum allowable sides of the vine, given the surroundings + NIBBLETYPE GetMaxMeta(cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) + { + static const struct { - return true; - } - - BLOCKTYPE TopBlock = a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ); - if (g_BlockIsSolid[TopBlock] || (TopBlock == E_BLOCK_LEAVES)) + int x, z; + int Bit; + } Coords[] = { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); - BLOCKTYPE BaseBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - if (!g_BlockIsSolid[BaseBlock] && (BaseBlock != E_BLOCK_LEAVES)) + { 0, 1, 1}, // south, ZP + {-1, 0, 2}, // west, XM + { 0, -1, 4}, // north, ZM + { 1, 0, 8}, // east, XP + } ; + int res = 0; + for (int i = 0; i < ARRAYCOUNT(Coords); i++) + { + BLOCKTYPE BlockType; + NIBBLETYPE BlockMeta; + if ( + a_Chunk.UnboundedRelGetBlock(a_RelX + Coords[i].x, a_RelY, a_RelZ + Coords[i].z, BlockType, BlockMeta) && + IsBlockAttachable(BlockType) + ) { - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false); - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_VINES, 0); + res |= Coords[i].Bit; } - return true; } - - AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, true); - BLOCKTYPE BaseBlock = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); - return (g_BlockIsSolid[BaseBlock] || (BaseBlock == E_BLOCK_LEAVES)); + return res; } - - - virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + + + void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override { - char Dir = cVine::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ)); - return CanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Dir); + NIBBLETYPE CurMeta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); + NIBBLETYPE MaxMeta = GetMaxMeta(a_Chunk, a_RelX, a_RelY, a_RelZ); + + // Check if vine above us, add its meta to MaxMeta + if ((a_RelY < cChunkDef::Height - 1) && (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == m_BlockType)) + { + MaxMeta |= a_Chunk.GetMeta(a_RelX, a_RelY + 1, a_RelZ); + } + + NIBBLETYPE Common = CurMeta & MaxMeta; // Neighbors that we have and are legal + if (Common != CurMeta) + { + // There is a neighbor missing, need to update the meta or even destroy the block + bool HasTop = (a_RelY < cChunkDef::Height - 1) && IsBlockAttachable(a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ)); + if ((Common == 0) && !HasTop) + { + // The vine just lost all its support, destroy the block: + if (DoesDropOnUnsuitable()) + { + int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; + int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; + DropBlock(a_Chunk.GetWorld(), NULL, BlockX, a_RelY, BlockZ); + } + a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); + return; + } + a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, m_BlockType, Common); + } + else + { + // Wake up the simulators for this block: + int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width; + int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; + a_Chunk.GetWorld()->GetSimulatorManager()->WakeUp(BlockX, a_RelY, BlockZ, &a_Chunk); + } } diff --git a/source/Chunk.cpp b/source/Chunk.cpp index 8165ee5b6..d8dfb79f8 100644 --- a/source/Chunk.cpp +++ b/source/Chunk.cpp @@ -509,18 +509,17 @@ void cChunk::CheckBlocks(void) { return; } - std::deque< unsigned int > ToTickBlocks = m_ToTickBlocks; - m_ToTickBlocks.clear(); + std::vector ToTickBlocks; + std::swap(m_ToTickBlocks, ToTickBlocks); Lock2.Unlock(); - for (std::deque< unsigned int >::const_iterator itr = ToTickBlocks.begin(); itr != ToTickBlocks.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 WorldPos = PositionToWorldPosition( BlockPos ); cBlockHandler * Handler = BlockHandler(GetBlock(index)); - Handler->Check(m_World, WorldPos.x, WorldPos.y, WorldPos.z); + Handler->Check(BlockPos.x, BlockPos.y, BlockPos.z, *this); } // for itr - ToTickBlocks[] } @@ -827,9 +826,9 @@ void cChunk::GrowCactus(int a_RelX, int a_RelY, int a_RelZ, int a_NumBlocks) -bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) +bool cChunk::UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const { - if ((a_RelY < 0) || (a_RelY > cChunkDef::Height)) + if ((a_RelY < 0) || (a_RelY >= cChunkDef::Height)) { LOGWARNING("UnboundedRelGetBlock(): requesting a block with a_RelY out of range: %d", a_RelY); return false; @@ -1821,20 +1820,33 @@ bool cChunk::GetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_ -BLOCKTYPE cChunk::GetBlock( int a_X, int a_Y, int a_Z ) +BLOCKTYPE cChunk::GetBlock(int a_RelX, int a_RelY, int a_RelZ) const { - if ((a_X < 0) || (a_X >= Width) || (a_Y < 0) || (a_Y >= Height) || (a_Z < 0) || (a_Z >= Width)) return 0; // Clip + if ( + (a_RelX < 0) || (a_RelX >= Width) || + (a_RelY < 0) || (a_RelY >= Height) || + (a_RelZ < 0) || (a_RelZ >= Width) + ) + { + ASSERT(!"GetBlock(x, y, z) out of bounds!"); + return 0; // Clip + } - return m_BlockTypes[ MakeIndexNoCheck( a_X, a_Y, a_Z ) ]; + return m_BlockTypes[MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ)]; } -BLOCKTYPE cChunk::GetBlock( int a_BlockIdx ) +BLOCKTYPE cChunk::GetBlock(int a_BlockIdx) const { - if( a_BlockIdx < 0 || a_BlockIdx >= NumBlocks ) return 0; + if ((a_BlockIdx < 0) || (a_BlockIdx >= NumBlocks)) + { + ASSERT(!"GetBlock(idx) out of bounds!"); + return 0; + } + return m_BlockTypes[ a_BlockIdx ]; } diff --git a/source/Chunk.h b/source/Chunk.h index ee80a0be8..bf590ee7e 100644 --- a/source/Chunk.h +++ b/source/Chunk.h @@ -127,10 +127,11 @@ public: void Tick(float a_Dt, MTRand & a_TickRandom); - int GetPosX() { return m_PosX; } - int GetPosY() { return m_PosY; } - int GetPosZ() { return m_PosZ; } - cWorld * GetWorld() { return m_World; } + int GetPosX(void) const { return m_PosX; } + int GetPosY(void) const { return m_PosY; } + int GetPosZ(void) const { return m_PosZ; } + + cWorld * GetWorld(void) const { return m_World; } void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); // SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense @@ -143,8 +144,8 @@ public: 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. - BLOCKTYPE GetBlock( int a_X, int a_Y, int a_Z ); - BLOCKTYPE GetBlock( int a_BlockIdx ); + 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); void GetBlockInfo (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); @@ -252,16 +253,16 @@ public: m_BlockTickZ = a_RelZ; } - inline NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockMeta, a_RelX, a_RelY, a_RelZ); } - inline NIBBLETYPE GetMeta(int a_BlockIdx) {return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); } + 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 GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); } - inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ); } + 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); } /// 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; only usable in Tick() - bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); + bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; /// Same as SetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success; only usable in Tick() bool UnboundedRelSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); @@ -285,9 +286,9 @@ 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 - cCriticalSection m_CSBlockLists; - std::deque< unsigned int > m_ToTickBlocks; - sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients + cCriticalSection m_CSBlockLists; + std::vector m_ToTickBlocks; + sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients // A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers cClientHandleList m_LoadedByClient; diff --git a/source/Vine.h b/source/Vine.h index 77fc554d7..7abf3992b 100644 --- a/source/Vine.h +++ b/source/Vine.h @@ -1,41 +1,42 @@ + #pragma once -class cVine // tolua_export -{ // tolua_export + + + + +// tolua_begin +class cVine +{ public: - static NIBBLETYPE DirectionToMetaData( char a_Direction ) // tolua_export - { // tolua_export - switch (a_Direction) + static NIBBLETYPE DirectionToMetaData(char a_BlockFace) + { + switch (a_BlockFace) { - case 0x2: - return 0x1; - case 0x3: - return 0x4; - case 0x4: - return 0x8; - case 0x5: - return 0x2; - default: - return 0x0; - }; - } // tolua_export - - static char MetaDataToDirection(NIBBLETYPE a_MetaData ) // tolua_export - { // tolua_export + case BLOCK_FACE_NORTH: return 0x1; + case BLOCK_FACE_SOUTH: return 0x4; + case BLOCK_FACE_WEST: return 0x8; + case BLOCK_FACE_EAST: return 0x2; + default: return 0x0; + } + } + + + static char MetaDataToDirection(NIBBLETYPE a_MetaData) + { switch(a_MetaData) { - case 0x1: - return 0x2; - case 0x4: - return 0x3; - case 0x8: - return 0x4; - case 0x2: - return 0x5; - default: - return 0x1; - }; - } // tolua_export - -}; // tolua_export + case 0x1: return BLOCK_FACE_NORTH; + case 0x4: return BLOCK_FACE_SOUTH; + case 0x8: return BLOCK_FACE_WEST; + case 0x2: return BLOCK_FACE_EAST; + default: return BLOCK_FACE_TOP; + } + } +} ; +// tolua_end + + + + -- cgit v1.2.3