Replaced the usage of pistonMeta with a direction vector to allow better meta value abstraction
This commit is contained in:
parent
ceec6c936d
commit
f35060e8b5
@ -14,22 +14,6 @@
|
||||
|
||||
|
||||
|
||||
#define AddPistonDir(x, y, z, dir, amount) \
|
||||
switch (dir & 0x07) \
|
||||
{ \
|
||||
case 0: (y) -= (amount); break; \
|
||||
case 1: (y) += (amount); break; \
|
||||
case 2: (z) -= (amount); break; \
|
||||
case 3: (z) += (amount); break; \
|
||||
case 4: (x) -= (amount); break; \
|
||||
case 5: (x) += (amount); break; \
|
||||
default: \
|
||||
{ \
|
||||
LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, dir & 0x07); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PISTON_MAX_PUSH_DISTANCE 12
|
||||
|
||||
|
||||
@ -48,10 +32,10 @@ void cBlockPistonHandler::OnDestroyed(cChunkInterface & a_ChunkInterface, cWorld
|
||||
{
|
||||
NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
|
||||
int newX = a_BlockX;
|
||||
int newY = a_BlockY;
|
||||
int newZ = a_BlockZ;
|
||||
AddPistonDir(newX, newY, newZ, OldMeta, 1);
|
||||
const Vector3i pushDir = GetDirectionVec(OldMeta);
|
||||
int newX = a_BlockX + pushDir.x;
|
||||
int newY = a_BlockY + pushDir.y;
|
||||
int newZ = a_BlockZ + pushDir.z;
|
||||
|
||||
if (a_ChunkInterface.GetBlock(newX, newY, newZ) == E_BLOCK_PISTON_EXTENSION)
|
||||
{
|
||||
@ -89,9 +73,31 @@ bool cBlockPistonHandler::GetPlacementBlockTypeMeta(
|
||||
|
||||
|
||||
|
||||
Vector3i cBlockPistonHandler::GetDirectionVec(int a_PistonMeta)
|
||||
{
|
||||
switch (a_PistonMeta & 0x07)
|
||||
{
|
||||
case 0: return Vector3i( 0, -1, 0);
|
||||
case 1: return Vector3i( 0, 1, 0);
|
||||
case 2: return Vector3i( 0, 0, -1);
|
||||
case 3: return Vector3i( 0, 0, 1);
|
||||
case 4: return Vector3i(-1, 0, 0);
|
||||
case 5: return Vector3i( 1, 0, 0);
|
||||
default:
|
||||
{
|
||||
LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, a_PistonMeta & 0x07);
|
||||
return Vector3i();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cBlockPistonHandler::CanPushBlock(
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable,
|
||||
std::unordered_set<Vector3i, VectorHasher<int>> & a_BlocksPushed, NIBBLETYPE a_PistonMeta
|
||||
std::unordered_set<Vector3i, VectorHasher<int>> & a_BlocksPushed, const Vector3i & a_PushDir
|
||||
)
|
||||
{
|
||||
const static std::array<Vector3i, 6> pushingDirs = {{ Vector3i(-1, 0, 0), Vector3i(1, 0, 0), Vector3i(0, -1, 0), Vector3i(0, 1, 0),
|
||||
@ -133,15 +139,14 @@ bool cBlockPistonHandler::CanPushBlock(
|
||||
// Try to push the other directions
|
||||
for(const Vector3i & testDir : pushingDirs)
|
||||
{
|
||||
if(!CanPushBlock(a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, a_World, false, a_BlocksPushed, a_PistonMeta))
|
||||
if(!CanPushBlock(a_BlockX + testDir.x, a_BlockY + testDir.y, a_BlockZ + testDir.z, a_World, false, a_BlocksPushed, a_PushDir))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, a_PistonMeta, 1);
|
||||
return CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, true, a_BlocksPushed, a_PistonMeta);
|
||||
return CanPushBlock(a_BlockX + a_PushDir.x, a_BlockY + a_PushDir.y, a_BlockZ + a_PushDir.z, a_World, true, a_BlocksPushed, a_PushDir);
|
||||
}
|
||||
|
||||
|
||||
@ -160,24 +165,22 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ,
|
||||
return;
|
||||
}
|
||||
|
||||
int moveX = a_BlockX;
|
||||
int moveY = a_BlockY;
|
||||
int moveZ = a_BlockZ;
|
||||
Vector3i pushDir = GetDirectionVec(pistonMeta);
|
||||
int moveX = a_BlockX + pushDir.x;
|
||||
int moveY = a_BlockY + pushDir.y;
|
||||
int moveZ = a_BlockZ + pushDir.z;
|
||||
|
||||
AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1);
|
||||
std::unordered_set<Vector3i, VectorHasher<int>> blocksPushed;
|
||||
if (!CanPushBlock(moveX, moveY, moveZ, a_World, true, blocksPushed, pistonMeta))
|
||||
if (!CanPushBlock(moveX, moveY, moveZ, a_World, true, blocksPushed, pushDir))
|
||||
{
|
||||
// Can't push anything, bail out
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3i pistonMoveVec;
|
||||
AddPistonDir(pistonMoveVec.x, pistonMoveVec.y, pistonMoveVec.z, pistonMeta, 1);
|
||||
std::vector<Vector3i> sortedBlocks(blocksPushed.begin(), blocksPushed.end());
|
||||
std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pistonMoveVec](const Vector3i & a, const Vector3i & b)
|
||||
std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pushDir](const Vector3i & a, const Vector3i & b)
|
||||
{
|
||||
return a.Dot(pistonMoveVec) > b.Dot(pistonMoveVec);
|
||||
return a.Dot(pushDir) > b.Dot(pushDir);
|
||||
});
|
||||
|
||||
a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 0, pistonMeta, pistonBlock);
|
||||
@ -193,7 +196,9 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ,
|
||||
a_World->GetBlockTypeMeta(moveX, moveY, moveZ, moveBlock, moveMeta);
|
||||
a_World->SetBlock(moveX, moveY, moveZ, E_BLOCK_AIR, 0);
|
||||
|
||||
AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1);
|
||||
moveX += pushDir.x;
|
||||
moveY += pushDir.y;
|
||||
moveZ += pushDir.z;
|
||||
|
||||
if (cBlockInfo::IsPistonBreakable(moveBlock))
|
||||
{
|
||||
@ -211,7 +216,9 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ,
|
||||
}
|
||||
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8);
|
||||
AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1);
|
||||
a_BlockX += pushDir.x;
|
||||
a_BlockY += pushDir.y;
|
||||
a_BlockZ += pushDir.z;
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0));
|
||||
}
|
||||
|
||||
@ -231,18 +238,18 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3i pushDir = GetDirectionVec(pistonMeta);
|
||||
|
||||
// Check the extension:
|
||||
AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 1);
|
||||
if (a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ) != E_BLOCK_PISTON_EXTENSION)
|
||||
if (a_World->GetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z) != E_BLOCK_PISTON_EXTENSION)
|
||||
{
|
||||
LOGD("%s: Piston without an extension - still extending, or just in an invalid state?", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove Extension
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0);
|
||||
a_World->SetBlock(a_BlockX + pushDir.x, a_BlockY + pushDir.y, a_BlockZ + pushDir.z, E_BLOCK_AIR, 0);
|
||||
|
||||
AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1);
|
||||
a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta & ~(8));
|
||||
a_World->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, 1, pistonMeta & ~(8), pistonBlock);
|
||||
a_World->BroadcastSoundEffect("tile.piston.in", static_cast<double>(a_BlockX), static_cast<double>(a_BlockY), static_cast<double>(a_BlockZ), 0.5f, 0.7f);
|
||||
@ -253,44 +260,23 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ
|
||||
return;
|
||||
}
|
||||
|
||||
AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, 2);
|
||||
a_BlockX += 2 * pushDir.x;
|
||||
a_BlockY += 2 * pushDir.y;
|
||||
a_BlockZ += 2 * pushDir.z;
|
||||
// Try to "push" the pulling block in the opposite direction
|
||||
switch(pistonMeta & 0x07)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
pistonMeta = 1 - pistonMeta;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
pistonMeta = 5 - pistonMeta;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
pistonMeta = 9 - pistonMeta;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
LOGWARNING("%s: invalid direction %d, ignoring", __FUNCTION__, pistonMeta & 0x07); \
|
||||
break;
|
||||
}
|
||||
}
|
||||
pushDir *= -1;
|
||||
|
||||
std::unordered_set<Vector3i, VectorHasher<int>> pushedBlocks;
|
||||
if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, false, pushedBlocks, pistonMeta))
|
||||
if (!CanPushBlock(a_BlockX, a_BlockY, a_BlockZ, a_World, false, pushedBlocks, pushDir))
|
||||
{
|
||||
// Not pushable, bail out
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3i pistonMoveVec;
|
||||
AddPistonDir(pistonMoveVec.x, pistonMoveVec.y, pistonMoveVec.z, pistonMeta, 1);
|
||||
std::vector<Vector3i> sortedBlocks(pushedBlocks.begin(), pushedBlocks.end());
|
||||
std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pistonMoveVec](const Vector3i & a, const Vector3i & b)
|
||||
std::sort(sortedBlocks.begin(), sortedBlocks.end(), [pushDir](const Vector3i & a, const Vector3i & b)
|
||||
{
|
||||
return a.Dot(pistonMoveVec) > b.Dot(pistonMoveVec);
|
||||
return a.Dot(pushDir) > b.Dot(pushDir);
|
||||
});
|
||||
|
||||
int moveX, moveY, moveZ;
|
||||
@ -304,7 +290,9 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ
|
||||
a_World->GetBlockTypeMeta(moveX, moveY, moveZ, moveBlock, moveMeta);
|
||||
a_World->SetBlock(moveX, moveY, moveZ, E_BLOCK_AIR, 0);
|
||||
|
||||
AddPistonDir(moveX, moveY, moveZ, pistonMeta, 1);
|
||||
moveX += pushDir.x;
|
||||
moveY += pushDir.y;
|
||||
moveZ += pushDir.z;
|
||||
|
||||
if (cBlockInfo::IsPistonBreakable(moveBlock))
|
||||
{
|
||||
@ -342,10 +330,10 @@ void cBlockPistonHeadHandler::OnDestroyedByPlayer(cChunkInterface & a_ChunkInter
|
||||
{
|
||||
NIBBLETYPE OldMeta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
|
||||
|
||||
int newX = a_BlockX;
|
||||
int newY = a_BlockY;
|
||||
int newZ = a_BlockZ;
|
||||
AddPistonDir(newX, newY, newZ, OldMeta, -1);
|
||||
Vector3i pushDir = cBlockPistonHandler::GetDirectionVec(OldMeta);
|
||||
int newX = a_BlockX - pushDir.x;
|
||||
int newY = a_BlockY - pushDir.y;
|
||||
int newZ = a_BlockZ - pushDir.z;
|
||||
|
||||
BLOCKTYPE Block = a_ChunkInterface.GetBlock(newX, newY, newZ);
|
||||
if ((Block == E_BLOCK_STICKY_PISTON) || (Block == E_BLOCK_PISTON))
|
||||
|
@ -81,6 +81,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static Vector3i GetDirectionVec(int a_PistonMeta);
|
||||
|
||||
static void ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
||||
static void RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World);
|
||||
|
||||
@ -157,7 +159,7 @@ private:
|
||||
/** Tries to push a block and increases the pushed blocks variable. Returns true if the block is pushable */
|
||||
static bool CanPushBlock(
|
||||
int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, bool a_RequirePushable,
|
||||
std::unordered_set<Vector3i, VectorHasher<int>> & a_BlocksPushed, NIBBLETYPE a_PistonMeta
|
||||
std::unordered_set<Vector3i, VectorHasher<int>> & a_BlocksPushed, const Vector3i & a_PushDir
|
||||
);
|
||||
} ;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user