1
0

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
This commit is contained in:
madmaxoft@gmail.com 2013-03-15 20:18:11 +00:00
parent 57e56ae561
commit 8090c13cde
22 changed files with 419 additions and 227 deletions

View File

@ -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)) if ((Surface != E_BLOCK_SAND) && (Surface != E_BLOCK_CACTUS))
{ {
// Cactus can only be placed on sand and itself // Cactus can only be placed on sand and itself
@ -34,15 +38,28 @@ public:
} }
// Check surroundings. Cacti may ONLY be surrounded by air // Check surroundings. Cacti may ONLY be surrounded by air
if ( static const struct
(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)
)
{ {
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; return true;
} }

View File

@ -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));
} }

View File

@ -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));
} }

View File

@ -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));
} }

View File

@ -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) switch (m_BlockType)
{ {
case E_BLOCK_STATIONARY_LAVA: 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; break;
} }
case E_BLOCK_STATIONARY_WATER: 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; break;
} }
} }
super::Check(a_World, a_BlockX, a_BlockY, a_BlockZ); super::Check(a_RelX, a_RelY, a_RelZ, a_Chunk);
} }
} ; } ;

View File

@ -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) bool cBlockHandler::CanBeAt(int a_BlockX, int a_BlockY, int a_BlockZ, const cChunk & a_Chunk)
{
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)
{ {
return true; 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()) 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 else
{ {
// Wake up the simulators for this block: // 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);
} }
} }

View File

@ -3,6 +3,7 @@
#include "../Defines.h" #include "../Defines.h"
#include "../Item.h" #include "../Item.h"
#include "../Chunk.h"
@ -74,14 +75,14 @@ public:
/// Returns step sound name of block /// Returns step sound name of block
virtual const char * GetStepSound(void); virtual const char * GetStepSound(void);
/// Checks if the block can stay at the specified coords in the world /// Checks if the block can stay at the specified relative coords in the chunk
virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ); 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. /** Checks if the block can be placed at this point.
Default: CanBeAt(...) Default: CanBeAt(...)
NOTE: This call doesn't actually place the block 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 /// 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); virtual bool DoesAllowBlockOnTop(void);
@ -109,7 +110,7 @@ public:
By default drops if position no more suitable (CanBeAt(), DoesDropOnUnsuitable(), Drop()), By default drops if position no more suitable (CanBeAt(), DoesDropOnUnsuitable(), Drop()),
and wakes up all simulators on the block. 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 /// Get the blockhandler for a specific block id

View File

@ -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)) // TODO: Use cTorch::AdjustCoordsByMeta(), then cChunk::UnboundedRelGetBlock() and finally some comparison
{ char BlockFace = cLadder::MetaDataToDirection(a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
return true; int BlockX = a_RelX + a_Chunk.GetPosX() * cChunkDef::Width;
} int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width;
return (FindSuitableBlockFace(a_World, a_BlockX, a_BlockY, a_BlockZ) != BLOCK_FACE_BOTTOM); return LadderCanBePlacedAt(a_Chunk.GetWorld(), BlockX, a_RelY, BlockZ, BlockFace);
}
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);
} }

View File

@ -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_GLASS:
case E_BLOCK_CACTUS: case E_BLOCK_CACTUS:

View File

@ -8,19 +8,36 @@
/// Meta values for the rail
enum ENUM_RAIL_DIRECTIONS enum ENUM_RAIL_DIRECTIONS
{ {
E_RAIL_NORTH_SOUTH = 0, E_RAIL_NORTH_SOUTH = 0,
E_RAIL_EAST_WEST = 1, E_RAIL_EAST_WEST = 1,
E_RAIL_ASCEND_EAST = 2, E_RAIL_ASCEND_EAST = 2,
E_RAIL_ASCEND_WEST = 3, E_RAIL_ASCEND_WEST = 3,
E_RAIL_ASCEND_NORTH = 4, E_RAIL_ASCEND_NORTH = 4,
E_RAIL_ASCEND_SOUTH = 5, E_RAIL_ASCEND_SOUTH = 5,
E_RAIL_CURVED_SOUTH_EAST = 6, E_RAIL_CURVED_SOUTH_EAST = 6,
E_RAIL_CURVED_SOUTH_WEST = 7, E_RAIL_CURVED_SOUTH_WEST = 7,
E_RAIL_CURVED_NORTH_WEST = 8, 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 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; 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) switch (Meta)
{ {
case E_RAIL_ASCEND_EAST: 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: 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: 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: 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; return true;
@ -159,16 +175,16 @@ public:
} }
if (RailsCnt > 1) if (RailsCnt > 1)
{ {
if (Neighbors[3] && Neighbors[0]) return E_RAIL_CURVED_SOUTH_EAST; 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[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[0]) return E_RAIL_CURVED_NORTH_EAST;
else if(Neighbors[2] && Neighbors[1]) return E_RAIL_CURVED_NORTH_WEST; 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[7] && Neighbors[2]) return E_RAIL_ASCEND_SOUTH;
else if(Neighbors[3] && Neighbors[6]) return E_RAIL_ASCEND_NORTH; 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[5] && Neighbors[0]) return E_RAIL_ASCEND_WEST;
else if(Neighbors[4] && Neighbors[1]) return E_RAIL_ASCEND_EAST; 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[0] && Neighbors[1]) return E_RAIL_EAST_WEST;
else if(Neighbors[2] && Neighbors[3]) return E_RAIL_NORTH_SOUTH; else if (Neighbors[2] && Neighbors[3]) return E_RAIL_NORTH_SOUTH;
ASSERT(!"Weird neighbor count"); ASSERT(!"Weird neighbor count");
} }
return Meta; return Meta;
@ -177,68 +193,130 @@ public:
bool IsUnstable(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) 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); NIBBLETYPE Meta = a_World->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
switch (Meta) switch (Meta)
{ {
case E_RAIL_NORTH_SOUTH: case E_RAIL_NORTH_SOUTH:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH, E_PURE_DOWN) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH, E_PURE_DOWN)) return true; 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; break;
} }
case E_RAIL_EAST_WEST: case E_RAIL_EAST_WEST:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST, E_PURE_DOWN) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST, E_PURE_DOWN)) return true; 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; break;
} }
case E_RAIL_ASCEND_EAST: case E_RAIL_ASCEND_EAST:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_EAST) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)) return true; 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; break;
} }
case E_RAIL_ASCEND_WEST: case E_RAIL_ASCEND_WEST:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_WEST)) return true; 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; break;
} }
case E_RAIL_ASCEND_NORTH: case E_RAIL_ASCEND_NORTH:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_NORTH) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH)) return true; 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; break;
} }
case E_RAIL_ASCEND_SOUTH: case E_RAIL_ASCEND_SOUTH:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY + 1, a_BlockZ, BLOCK_FACE_SOUTH)) return true; 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; break;
} }
case E_RAIL_CURVED_SOUTH_EAST: case E_RAIL_CURVED_SOUTH_EAST:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST)) return true; 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; break;
} }
case E_RAIL_CURVED_SOUTH_WEST: case E_RAIL_CURVED_SOUTH_WEST:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_SOUTH) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)) return true; 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; break;
} }
case E_RAIL_CURVED_NORTH_WEST: case E_RAIL_CURVED_NORTH_WEST:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_WEST)) return true; 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; break;
} }
case E_RAIL_CURVED_NORTH_EAST: case E_RAIL_CURVED_NORTH_EAST:
{ {
if(IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_NORTH) || if (
IsNotConnected(a_World, a_BlockX, a_BlockY, a_BlockZ, BLOCK_FACE_EAST)) return true; 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; 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); AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false);
NIBBLETYPE Meta; NIBBLETYPE Meta;

View File

@ -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)]);
} }

View File

@ -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));
} }

View File

@ -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));
} }

View File

@ -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 (a_RelY > 0) && g_BlockIsSnowable[a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)];
return g_BlockIsSnowable[UnderlyingBlock];
} }

View File

@ -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));
} }

View File

@ -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_DIRT:
case E_BLOCK_GRASS: case E_BLOCK_GRASS:
case E_BLOCK_FARMLAND: case E_BLOCK_FARMLAND:
case E_BLOCK_SAND: 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: case E_BLOCK_SUGARCANE:
{ {

View File

@ -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));
} }

View File

@ -98,6 +98,7 @@ public:
} }
/*
virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override 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)) 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); 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)); // TODO: Use cTorch::AdjustCoordsByMeta(), then cChunk::UnboundedRelGetBlock() and finally some comparison
return TorchCanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Face); 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);
} }

View File

@ -25,45 +25,98 @@ public:
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) 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_BlockType = m_BlockType;
a_BlockMeta = cVine::DirectionToMetaData(a_BlockFace);
return true; 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 ( return (a_BlockType == E_BLOCK_LEAVES) || g_BlockIsSolid[a_BlockType];
(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 true;
}
BLOCKTYPE TopBlock = a_World->GetBlock( a_BlockX, a_BlockY + 1, a_BlockZ);
if (g_BlockIsSolid[TopBlock] || (TopBlock == E_BLOCK_LEAVES))
{
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))
{
AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, false);
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_VINES, 0);
}
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));
} }
virtual bool CanBeAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ) override /// 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)
{ {
char Dir = cVine::MetaDataToDirection(a_World->GetBlockMeta( a_BlockX, a_BlockY, a_BlockZ)); static const struct
return CanBePlacedAt(a_World, a_BlockX, a_BlockY, a_BlockZ, Dir); {
int x, z;
int Bit;
} Coords[] =
{
{ 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)
)
{
res |= Coords[i].Bit;
}
}
return res;
}
void Check(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override
{
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);
}
} }

View File

@ -509,18 +509,17 @@ void cChunk::CheckBlocks(void)
{ {
return; return;
} }
std::deque< unsigned int > ToTickBlocks = m_ToTickBlocks; std::vector<unsigned int> ToTickBlocks;
m_ToTickBlocks.clear(); std::swap(m_ToTickBlocks, ToTickBlocks);
Lock2.Unlock(); Lock2.Unlock();
for (std::deque< unsigned int >::const_iterator itr = ToTickBlocks.begin(); itr != ToTickBlocks.end(); ++itr) for (std::vector<unsigned int>::const_iterator itr = ToTickBlocks.begin(), end = ToTickBlocks.end(); itr != end; ++itr)
{ {
unsigned int index = (*itr); unsigned int index = (*itr);
Vector3i BlockPos = IndexToCoordinate(index); Vector3i BlockPos = IndexToCoordinate(index);
Vector3i WorldPos = PositionToWorldPosition( BlockPos );
cBlockHandler * Handler = BlockHandler(GetBlock(index)); 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[] } // 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); LOGWARNING("UnboundedRelGetBlock(): requesting a block with a_RelY out of range: %d", a_RelY);
return false; 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 ]; return m_BlockTypes[ a_BlockIdx ];
} }

View File

@ -127,10 +127,11 @@ public:
void Tick(float a_Dt, MTRand & a_TickRandom); void Tick(float a_Dt, MTRand & a_TickRandom);
int GetPosX() { return m_PosX; } int GetPosX(void) const { return m_PosX; }
int GetPosY() { return m_PosY; } int GetPosY(void) const { return m_PosY; }
int GetPosZ() { return m_PosZ; } int GetPosZ(void) const { return m_PosZ; }
cWorld * GetWorld() { return m_World; }
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 );
// SetBlock() does a lot of work (heightmap, tickblocks, blockentities) so a BlockIdx version doesn't make sense // 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 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 ); // 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_RelX, int a_RelY, int a_RelZ) const;
BLOCKTYPE GetBlock( int a_BlockIdx ); BLOCKTYPE GetBlock(int a_BlockIdx) const;
void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); 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); 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; 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_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) {return cChunkDef::GetNibble(m_BlockMeta, a_BlockIdx); } 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_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 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 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) {return cChunkDef::GetNibble(m_BlockSkyLight, 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() /// 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() /// 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); 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_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 bool m_HasLoadFailed; // True if chunk failed to load and hasn't been generated yet since then
cCriticalSection m_CSBlockLists; cCriticalSection m_CSBlockLists;
std::deque< unsigned int > m_ToTickBlocks; std::vector<unsigned int> m_ToTickBlocks;
sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients 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 // A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
cClientHandleList m_LoadedByClient; cClientHandleList m_LoadedByClient;

View File

@ -1,41 +1,42 @@
#pragma once #pragma once
class cVine // tolua_export
{ // tolua_export
// tolua_begin
class cVine
{
public: public:
static NIBBLETYPE DirectionToMetaData( char a_Direction ) // tolua_export static NIBBLETYPE DirectionToMetaData(char a_BlockFace)
{ // tolua_export {
switch (a_Direction) switch (a_BlockFace)
{ {
case 0x2: case BLOCK_FACE_NORTH: return 0x1;
return 0x1; case BLOCK_FACE_SOUTH: return 0x4;
case 0x3: case BLOCK_FACE_WEST: return 0x8;
return 0x4; case BLOCK_FACE_EAST: return 0x2;
case 0x4: default: return 0x0;
return 0x8; }
case 0x5: }
return 0x2;
default:
return 0x0;
};
} // tolua_export
static char MetaDataToDirection(NIBBLETYPE a_MetaData ) // tolua_export
{ // tolua_export static char MetaDataToDirection(NIBBLETYPE a_MetaData)
{
switch(a_MetaData) switch(a_MetaData)
{ {
case 0x1: case 0x1: return BLOCK_FACE_NORTH;
return 0x2; case 0x4: return BLOCK_FACE_SOUTH;
case 0x4: case 0x8: return BLOCK_FACE_WEST;
return 0x3; case 0x2: return BLOCK_FACE_EAST;
case 0x8: default: return BLOCK_FACE_TOP;
return 0x4; }
case 0x2: }
return 0x5; } ;
default: // tolua_end
return 0x1;
};
} // tolua_export
}; // tolua_export