diff options
author | Alexander Harkness <bearbin@gmail.com> | 2013-07-29 13:13:03 +0200 |
---|---|---|
committer | Alexander Harkness <bearbin@gmail.com> | 2013-07-29 13:13:03 +0200 |
commit | 53e22b11857fed62e2313d6d84d90f88ed412ffb (patch) | |
tree | c61e56725da7dff0154d566722651e2c39c9d6c6 /source/Blocks/BlockRail.h | |
parent | WebAdmin: Removed the duplicate memory usage querying (diff) | |
download | cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.gz cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.bz2 cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.lz cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.xz cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.tar.zst cuberite-53e22b11857fed62e2313d6d84d90f88ed412ffb.zip |
Diffstat (limited to 'source/Blocks/BlockRail.h')
-rw-r--r-- | source/Blocks/BlockRail.h | 842 |
1 files changed, 421 insertions, 421 deletions
diff --git a/source/Blocks/BlockRail.h b/source/Blocks/BlockRail.h index 60865abf5..65d120923 100644 --- a/source/Blocks/BlockRail.h +++ b/source/Blocks/BlockRail.h @@ -1,421 +1,421 @@ -
-#pragma once
-
-#include "BlockEntity.h"
-#include "../World.h"
-
-
-
-
-
-/// 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_CURVED_SOUTH_EAST = 6,
- E_RAIL_CURVED_SOUTH_WEST = 7,
- E_RAIL_CURVED_NORTH_WEST = 8,
- 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
-{
- E_PURE_UPDOWN = 0,
- E_PURE_DOWN = 1,
- E_PURE_NONE = 2
-};
-
-
-
-
-
-class cBlockRailHandler :
- public cBlockHandler
-{
-public:
- cBlockRailHandler(BLOCKTYPE a_BlockType)
- : cBlockHandler(a_BlockType)
- {
- }
-
- virtual bool GetPlacementBlockTypeMeta(
- cWorld * a_World, 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
- ) override
- {
- a_BlockType = m_BlockType;
- a_BlockMeta = FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ);
- return true;
- }
-
-
- virtual void OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override
- {
- NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- if (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ) && (Meta != FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)))
- {
- a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ));
- }
- }
-
-
- virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override
- {
- if (a_RelY <= 0)
- {
- return false;
- }
- 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:
- case E_RAIL_ASCEND_WEST:
- case E_RAIL_ASCEND_NORTH:
- case E_RAIL_ASCEND_SOUTH:
- {
- // Mapping between the meta and the neighbors that need checking
- Meta -= E_RAIL_ASCEND_EAST; // Base index at zero
- static const struct
- {
- 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;
- }
- return g_BlockIsSolid[BlockType];
- }
- }
- return true;
- }
-
- NIBBLETYPE FindMeta(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ)
- {
- NIBBLETYPE Meta = 0;
- char RailsCnt = 0;
- bool Neighbors[8]; // 0 - EAST, 1 - WEST, 2 - NORTH, 3 - SOUTH, 4 - EAST UP, 5 - WEST UP, 6 - NORTH UP, 7 - SOUTH UP
- memset(Neighbors, false, sizeof(Neighbors));
- Neighbors[0] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN));
- Neighbors[1] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN));
- Neighbors[2] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN));
- Neighbors[3] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN));
- Neighbors[4] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST, E_PURE_NONE));
- Neighbors[5] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST, E_PURE_NONE));
- Neighbors[6] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_NONE));
- Neighbors[7] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_NONE));
- if (IsUnstable(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_EAST))
- Neighbors[0] = true;
- if (IsUnstable(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_WEST))
- Neighbors[1] = true;
- if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_NORTH))
- Neighbors[2] = true;
- if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_SOUTH))
- Neighbors[3] = true;
- for (int i = 0; i < 8; i++)
- {
- if (Neighbors[i])
- {
- RailsCnt++;
- }
- }
- if (RailsCnt == 1)
- {
- if (Neighbors[7]) return E_RAIL_ASCEND_SOUTH;
- else if (Neighbors[6]) return E_RAIL_ASCEND_NORTH;
- else if (Neighbors[5]) return E_RAIL_ASCEND_WEST;
- else if (Neighbors[4]) 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;
- }
- for (int i = 0; i < 4; i++)
- {
- if (Neighbors[i + 4])
- {
- Neighbors[i] = true;
- }
- }
- 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;
- ASSERT(!"Weird neighbor count");
- }
- return Meta;
- }
-
-
- 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;
- }
- 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;
- }
- 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;
- }
- 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;
- }
- 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;
- }
- 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;
- }
- 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;
- }
- 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;
- }
- 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;
- }
- 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;
- }
- 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;
- }
- break;
- }
- }
- return false;
- }
-
-
- 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;
- if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL)
- {
- if ((a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure != E_PURE_UPDOWN))
- {
- if ((a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure == E_PURE_NONE))
- {
- return true;
- }
- else
- {
- Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ);
- }
- }
- else
- {
- Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ);
- }
- }
- else
- {
- Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
- }
-
- switch (a_BlockFace)
- {
- case BLOCK_FACE_NORTH:
- {
- if (
- (Meta == E_RAIL_NORTH_SOUTH) ||
- (Meta == E_RAIL_ASCEND_NORTH) ||
- (Meta == E_RAIL_ASCEND_SOUTH) ||
- (Meta == E_RAIL_CURVED_SOUTH_EAST) ||
- (Meta == E_RAIL_CURVED_SOUTH_WEST)
- )
- {
- return false;
- }
- break;
- }
-
- case BLOCK_FACE_SOUTH:
- {
- if (
- (Meta == E_RAIL_NORTH_SOUTH) ||
- (Meta == E_RAIL_ASCEND_NORTH) ||
- (Meta == E_RAIL_ASCEND_SOUTH) ||
- (Meta == E_RAIL_CURVED_NORTH_EAST) ||
- (Meta == E_RAIL_CURVED_NORTH_WEST)
- )
- {
- return false;
- }
- break;
- }
-
- case BLOCK_FACE_EAST:
- {
- if (
- (Meta == E_RAIL_EAST_WEST) ||
- (Meta == E_RAIL_ASCEND_EAST) ||
- (Meta == E_RAIL_ASCEND_WEST) ||
- (Meta == E_RAIL_CURVED_SOUTH_WEST) ||
- (Meta == E_RAIL_CURVED_NORTH_WEST)
- )
- {
- return false;
- }
- break;
- }
- case BLOCK_FACE_WEST:
- {
- if (
- (Meta == E_RAIL_EAST_WEST) ||
- (Meta == E_RAIL_ASCEND_EAST) ||
- (Meta == E_RAIL_ASCEND_WEST) ||
- (Meta == E_RAIL_CURVED_SOUTH_EAST) ||
- (Meta == E_RAIL_CURVED_NORTH_EAST)
- )
- {
- return false;
- }
- break;
- }
- }
- return true;
- }
-} ;
-
-
-
-
+ +#pragma once + +#include "BlockEntity.h" +#include "../World.h" + + + + + +/// 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_CURVED_SOUTH_EAST = 6, + E_RAIL_CURVED_SOUTH_WEST = 7, + E_RAIL_CURVED_NORTH_WEST = 8, + 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 +{ + E_PURE_UPDOWN = 0, + E_PURE_DOWN = 1, + E_PURE_NONE = 2 +}; + + + + + +class cBlockRailHandler : + public cBlockHandler +{ +public: + cBlockRailHandler(BLOCKTYPE a_BlockType) + : cBlockHandler(a_BlockType) + { + } + + virtual bool GetPlacementBlockTypeMeta( + cWorld * a_World, 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 + ) override + { + a_BlockType = m_BlockType; + a_BlockMeta = FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ); + return true; + } + + + virtual void OnNeighborChanged(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override + { + NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + if (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ) && (Meta != FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ))) + { + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, m_BlockType, FindMeta(a_World, a_BlockX, a_BlockY, a_BlockZ)); + } + } + + + virtual bool CanBeAt(int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + if (a_RelY <= 0) + { + return false; + } + 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: + case E_RAIL_ASCEND_WEST: + case E_RAIL_ASCEND_NORTH: + case E_RAIL_ASCEND_SOUTH: + { + // Mapping between the meta and the neighbors that need checking + Meta -= E_RAIL_ASCEND_EAST; // Base index at zero + static const struct + { + 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; + } + return g_BlockIsSolid[BlockType]; + } + } + return true; + } + + NIBBLETYPE FindMeta(cWorld *a_World, int a_BlockX, int a_BlockY, int a_BlockZ) + { + NIBBLETYPE Meta = 0; + char RailsCnt = 0; + bool Neighbors[8]; // 0 - EAST, 1 - WEST, 2 - NORTH, 3 - SOUTH, 4 - EAST UP, 5 - WEST UP, 6 - NORTH UP, 7 - SOUTH UP + memset(Neighbors, false, sizeof(Neighbors)); + Neighbors[0] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN)); + Neighbors[1] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN)); + Neighbors[2] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN)); + Neighbors[3] = (IsUnstable(a_World, a_BlockX, a_BlockY, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN)); + Neighbors[4] = (IsUnstable(a_World, a_BlockX + 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST, E_PURE_NONE)); + Neighbors[5] = (IsUnstable(a_World, a_BlockX - 1, a_BlockY + 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST, E_PURE_NONE)); + Neighbors[6] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_NONE)); + Neighbors[7] = (IsUnstable(a_World, a_BlockX, a_BlockY + 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_NONE)); + if (IsUnstable(a_World, a_BlockX + 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_EAST)) + Neighbors[0] = true; + if (IsUnstable(a_World, a_BlockX - 1, a_BlockY - 1, a_BlockZ) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_WEST)) + Neighbors[1] = true; + if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ - 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_NORTH)) + Neighbors[2] = true; + if (IsUnstable(a_World, a_BlockX, a_BlockY - 1, a_BlockZ + 1) || !IsNotConnected(a_World, a_BlockX, a_BlockY - 1, a_BlockZ, BLOCK_FACE_SOUTH)) + Neighbors[3] = true; + for (int i = 0; i < 8; i++) + { + if (Neighbors[i]) + { + RailsCnt++; + } + } + if (RailsCnt == 1) + { + if (Neighbors[7]) return E_RAIL_ASCEND_SOUTH; + else if (Neighbors[6]) return E_RAIL_ASCEND_NORTH; + else if (Neighbors[5]) return E_RAIL_ASCEND_WEST; + else if (Neighbors[4]) 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; + } + for (int i = 0; i < 4; i++) + { + if (Neighbors[i + 4]) + { + Neighbors[i] = true; + } + } + 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; + ASSERT(!"Weird neighbor count"); + } + return Meta; + } + + + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + 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; + } + break; + } + } + return false; + } + + + 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; + if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_RAIL) + { + if ((a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure != E_PURE_UPDOWN)) + { + if ((a_World->GetBlock(a_BlockX, a_BlockY - 1, a_BlockZ) != E_BLOCK_RAIL) || (a_Pure == E_PURE_NONE)) + { + return true; + } + else + { + Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); + } + } + else + { + Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY + 1, a_BlockZ); + } + } + else + { + Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); + } + + switch (a_BlockFace) + { + case BLOCK_FACE_NORTH: + { + if ( + (Meta == E_RAIL_NORTH_SOUTH) || + (Meta == E_RAIL_ASCEND_NORTH) || + (Meta == E_RAIL_ASCEND_SOUTH) || + (Meta == E_RAIL_CURVED_SOUTH_EAST) || + (Meta == E_RAIL_CURVED_SOUTH_WEST) + ) + { + return false; + } + break; + } + + case BLOCK_FACE_SOUTH: + { + if ( + (Meta == E_RAIL_NORTH_SOUTH) || + (Meta == E_RAIL_ASCEND_NORTH) || + (Meta == E_RAIL_ASCEND_SOUTH) || + (Meta == E_RAIL_CURVED_NORTH_EAST) || + (Meta == E_RAIL_CURVED_NORTH_WEST) + ) + { + return false; + } + break; + } + + case BLOCK_FACE_EAST: + { + if ( + (Meta == E_RAIL_EAST_WEST) || + (Meta == E_RAIL_ASCEND_EAST) || + (Meta == E_RAIL_ASCEND_WEST) || + (Meta == E_RAIL_CURVED_SOUTH_WEST) || + (Meta == E_RAIL_CURVED_NORTH_WEST) + ) + { + return false; + } + break; + } + case BLOCK_FACE_WEST: + { + if ( + (Meta == E_RAIL_EAST_WEST) || + (Meta == E_RAIL_ASCEND_EAST) || + (Meta == E_RAIL_ASCEND_WEST) || + (Meta == E_RAIL_CURVED_SOUTH_EAST) || + (Meta == E_RAIL_CURVED_NORTH_EAST) + ) + { + return false; + } + break; + } + } + return true; + } +} ; + + + + |