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/BlockRail.h | 212 +++++++++++++++++++++++++++++++--------------- 1 file changed, 145 insertions(+), 67 deletions(-) (limited to 'source/Blocks/BlockRail.h') 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; -- cgit v1.2.3