Powered rails can kick-start minecarts (#3472)
This commit is contained in:
parent
e8fb85be88
commit
ff4be64edc
@ -445,6 +445,21 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
|
|||||||
AddSpeedZ(AccelDecelNegSpeed);
|
AddSpeedZ(AccelDecelNegSpeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If rail is powered check for nearby blocks that could kick-start the minecart
|
||||||
|
else if ((a_RailMeta & 0x8) == 0x8)
|
||||||
|
{
|
||||||
|
bool IsBlockZP = IsSolidBlockAtOffset(0, 0, 1);
|
||||||
|
bool IsBlockZM = IsSolidBlockAtOffset(0, 0, -1);
|
||||||
|
// Only kick-start the minecart if a block is on one side, but not both
|
||||||
|
if (IsBlockZM && !IsBlockZP)
|
||||||
|
{
|
||||||
|
AddSpeedZ(AccelDecelSpeed);
|
||||||
|
}
|
||||||
|
else if (!IsBlockZM && IsBlockZP)
|
||||||
|
{
|
||||||
|
AddSpeedZ(AccelDecelNegSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case E_META_RAIL_XM_XP: // EASTWEST
|
case E_META_RAIL_XM_XP: // EASTWEST
|
||||||
@ -471,6 +486,21 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
|
|||||||
AddSpeedX(AccelDecelNegSpeed);
|
AddSpeedX(AccelDecelNegSpeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If rail is powered check for nearby blocks that could kick-start the minecart
|
||||||
|
else if ((a_RailMeta & 0x8) == 0x8)
|
||||||
|
{
|
||||||
|
bool IsBlockXP = IsSolidBlockAtOffset(1, 0, 0);
|
||||||
|
bool IsBlockXM = IsSolidBlockAtOffset(-1, 0, 0);
|
||||||
|
// Only kick-start the minecart if a block is on one side, but not both
|
||||||
|
if (IsBlockXM && !IsBlockXP)
|
||||||
|
{
|
||||||
|
AddSpeedX(AccelDecelSpeed);
|
||||||
|
}
|
||||||
|
else if (!IsBlockXM && IsBlockXP)
|
||||||
|
{
|
||||||
|
AddSpeedX(AccelDecelNegSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case E_META_RAIL_ASCEND_XM: // ASCEND EAST
|
case E_META_RAIL_ASCEND_XM: // ASCEND EAST
|
||||||
@ -698,6 +728,20 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cMinecart::IsSolidBlockAtOffset(int a_XOffset, int a_YOffset, int a_ZOffset)
|
||||||
|
{
|
||||||
|
BLOCKTYPE Block = m_World->GetBlock(POSX_TOINT + a_XOffset, POSY_TOINT + a_YOffset, POSZ_TOINT + a_ZOffset);
|
||||||
|
if (IsBlockRail(Block) || !cBlockInfo::IsSolid(Block))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
||||||
{
|
{
|
||||||
switch (a_RailMeta)
|
switch (a_RailMeta)
|
||||||
@ -706,8 +750,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
|||||||
{
|
{
|
||||||
if (GetSpeedZ() > 0)
|
if (GetSpeedZ() > 0)
|
||||||
{
|
{
|
||||||
BLOCKTYPE Block = m_World->GetBlock(POSX_TOINT, POSY_TOINT, static_cast<int>(ceil(GetPosZ())));
|
if (IsSolidBlockAtOffset(0, 0, 1))
|
||||||
if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block))
|
|
||||||
{
|
{
|
||||||
// We could try to detect a block in front based purely on coordinates, but xoft made a bounding box system - why not use? :P
|
// We could try to detect a block in front based purely on coordinates, but xoft made a bounding box system - why not use? :P
|
||||||
cBoundingBox bbBlock(Vector3d(POSX_TOINT, POSY_TOINT, static_cast<int>(ceil(GetPosZ()))), 0.5, 1);
|
cBoundingBox bbBlock(Vector3d(POSX_TOINT, POSY_TOINT, static_cast<int>(ceil(GetPosZ()))), 0.5, 1);
|
||||||
@ -723,8 +766,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
|||||||
}
|
}
|
||||||
else if (GetSpeedZ() < 0)
|
else if (GetSpeedZ() < 0)
|
||||||
{
|
{
|
||||||
BLOCKTYPE Block = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT - 1);
|
if (IsSolidBlockAtOffset(0, 0, -1))
|
||||||
if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block))
|
|
||||||
{
|
{
|
||||||
cBoundingBox bbBlock(Vector3d(POSX_TOINT, POSY_TOINT, POSZ_TOINT - 1), 0.5, 1);
|
cBoundingBox bbBlock(Vector3d(POSX_TOINT, POSY_TOINT, POSZ_TOINT - 1), 0.5, 1);
|
||||||
cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ() - 1), GetWidth() / 2, GetHeight());
|
cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ() - 1), GetWidth() / 2, GetHeight());
|
||||||
@ -743,8 +785,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
|||||||
{
|
{
|
||||||
if (GetSpeedX() > 0)
|
if (GetSpeedX() > 0)
|
||||||
{
|
{
|
||||||
BLOCKTYPE Block = m_World->GetBlock(static_cast<int>(ceil(GetPosX())), POSY_TOINT, POSZ_TOINT);
|
if (IsSolidBlockAtOffset(1, 0, 0))
|
||||||
if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block))
|
|
||||||
{
|
{
|
||||||
cBoundingBox bbBlock(Vector3d(static_cast<int>(ceil(GetPosX())), POSY_TOINT, POSZ_TOINT), 0.5, 1);
|
cBoundingBox bbBlock(Vector3d(static_cast<int>(ceil(GetPosX())), POSY_TOINT, POSZ_TOINT), 0.5, 1);
|
||||||
cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight());
|
cBoundingBox bbMinecart(Vector3d(GetPosX(), floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight());
|
||||||
@ -759,8 +800,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
|||||||
}
|
}
|
||||||
else if (GetSpeedX() < 0)
|
else if (GetSpeedX() < 0)
|
||||||
{
|
{
|
||||||
BLOCKTYPE Block = m_World->GetBlock(POSX_TOINT - 1, POSY_TOINT, POSZ_TOINT);
|
if (IsSolidBlockAtOffset(-1, 0, 0))
|
||||||
if (!IsBlockRail(Block) && cBlockInfo::IsSolid(Block))
|
|
||||||
{
|
{
|
||||||
cBoundingBox bbBlock(Vector3d(POSX_TOINT - 1, POSY_TOINT, POSZ_TOINT), 0.5, 1);
|
cBoundingBox bbBlock(Vector3d(POSX_TOINT - 1, POSY_TOINT, POSZ_TOINT), 0.5, 1);
|
||||||
cBoundingBox bbMinecart(Vector3d(GetPosX() - 1, floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight());
|
cBoundingBox bbMinecart(Vector3d(GetPosX() - 1, floor(GetPosY()), GetPosZ()), GetWidth() / 2, GetHeight());
|
||||||
@ -777,13 +817,10 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
|||||||
}
|
}
|
||||||
case E_META_RAIL_CURVED_ZM_XM:
|
case E_META_RAIL_CURVED_ZM_XM:
|
||||||
{
|
{
|
||||||
BLOCKTYPE BlockXM = m_World->GetBlock(POSX_TOINT - 1, POSY_TOINT, POSZ_TOINT);
|
bool IsBlockXM = IsSolidBlockAtOffset(-1, 0, 0);
|
||||||
BLOCKTYPE BlockZM = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT - 1);
|
bool IsBlockZM = IsSolidBlockAtOffset(0, 0, -1);
|
||||||
|
|
||||||
if (
|
if (((GetSpeedZ() < 0) && IsBlockZM) || ((GetSpeedX() < 0) && IsBlockXM))
|
||||||
((GetSpeedZ() < 0) && (!IsBlockRail(BlockZM) && cBlockInfo::IsSolid(BlockZM))) ||
|
|
||||||
((GetSpeedX() < 0) && (!IsBlockRail(BlockXM) && cBlockInfo::IsSolid(BlockXM)))
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SetSpeed(0, 0, 0);
|
SetSpeed(0, 0, 0);
|
||||||
SetPosition(POSX_TOINT + 0.5, GetPosY(), POSZ_TOINT + 0.5);
|
SetPosition(POSX_TOINT + 0.5, GetPosY(), POSZ_TOINT + 0.5);
|
||||||
@ -794,13 +831,10 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
|||||||
}
|
}
|
||||||
case E_META_RAIL_CURVED_ZM_XP:
|
case E_META_RAIL_CURVED_ZM_XP:
|
||||||
{
|
{
|
||||||
BLOCKTYPE BlockXP = m_World->GetBlock(POSX_TOINT + 1, POSY_TOINT, POSZ_TOINT);
|
bool IsBlockXP = IsSolidBlockAtOffset(1, 0, 0);
|
||||||
BLOCKTYPE BlockZM = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT - 1);
|
bool IsBlockZM = IsSolidBlockAtOffset(0, 0, -1);
|
||||||
|
|
||||||
if (
|
if (((GetSpeedZ() < 0) && IsBlockZM) || ((GetSpeedX() > 0) && IsBlockXP))
|
||||||
((GetSpeedZ() < 0) && (!IsBlockRail(BlockZM) && cBlockInfo::IsSolid(BlockZM))) ||
|
|
||||||
((GetSpeedX() > 0) && (!IsBlockRail(BlockXP) && cBlockInfo::IsSolid(BlockXP)))
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SetSpeed(0, 0, 0);
|
SetSpeed(0, 0, 0);
|
||||||
SetPosition(POSX_TOINT + 0.5, GetPosY(), POSZ_TOINT + 0.5);
|
SetPosition(POSX_TOINT + 0.5, GetPosY(), POSZ_TOINT + 0.5);
|
||||||
@ -811,13 +845,10 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
|||||||
}
|
}
|
||||||
case E_META_RAIL_CURVED_ZP_XM:
|
case E_META_RAIL_CURVED_ZP_XM:
|
||||||
{
|
{
|
||||||
BLOCKTYPE BlockXM = m_World->GetBlock(POSX_TOINT - 1, POSY_TOINT, POSZ_TOINT);
|
bool IsBlockXM = IsSolidBlockAtOffset(-1, 0, 0);
|
||||||
BLOCKTYPE BlockZP = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT + 1);
|
bool IsBlockZP = IsSolidBlockAtOffset(0, 0, +1);
|
||||||
|
|
||||||
if (
|
if (((GetSpeedZ() > 0) && IsBlockZP) || ((GetSpeedX() < 0) && IsBlockXM))
|
||||||
((GetSpeedZ() > 0) && (!IsBlockRail(BlockZP) && cBlockInfo::IsSolid(BlockZP))) ||
|
|
||||||
((GetSpeedX() < 0) && (!IsBlockRail(BlockXM) && cBlockInfo::IsSolid(BlockXM)))
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SetSpeed(0, 0, 0);
|
SetSpeed(0, 0, 0);
|
||||||
SetPosition(POSX_TOINT + 0.5, GetPosY(), POSZ_TOINT + 0.5);
|
SetPosition(POSX_TOINT + 0.5, GetPosY(), POSZ_TOINT + 0.5);
|
||||||
@ -828,13 +859,10 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta)
|
|||||||
}
|
}
|
||||||
case E_META_RAIL_CURVED_ZP_XP:
|
case E_META_RAIL_CURVED_ZP_XP:
|
||||||
{
|
{
|
||||||
BLOCKTYPE BlockXP = m_World->GetBlock(POSX_TOINT + 1, POSY_TOINT, POSZ_TOINT);
|
bool IsBlockXP = IsSolidBlockAtOffset(1, 0, 0);
|
||||||
BLOCKTYPE BlockZP = m_World->GetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT + 1);
|
bool IsBlockZP = IsSolidBlockAtOffset(0, 0, 1);
|
||||||
|
|
||||||
if (
|
if (((GetSpeedZ() > 0) && IsBlockZP) || ((GetSpeedX() > 0) && IsBlockXP))
|
||||||
((GetSpeedZ() > 0) && (!IsBlockRail(BlockZP) && cBlockInfo::IsSolid(BlockZP))) ||
|
|
||||||
((GetSpeedX() > 0) && (!IsBlockRail(BlockXP) && cBlockInfo::IsSolid(BlockXP)))
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
SetSpeed(0, 0, 0);
|
SetSpeed(0, 0, 0);
|
||||||
SetPosition(POSX_TOINT + 0.5, GetPosY(), POSZ_TOINT + 0.5);
|
SetPosition(POSX_TOINT + 0.5, GetPosY(), POSZ_TOINT + 0.5);
|
||||||
|
@ -78,6 +78,8 @@ protected:
|
|||||||
void SnapToRail(NIBBLETYPE a_RailMeta);
|
void SnapToRail(NIBBLETYPE a_RailMeta);
|
||||||
/** Tests if a solid block is in front of a cart, and stops the cart (and returns true) if so; returns false if no obstruction */
|
/** Tests if a solid block is in front of a cart, and stops the cart (and returns true) if so; returns false if no obstruction */
|
||||||
bool TestBlockCollision(NIBBLETYPE a_RailMeta);
|
bool TestBlockCollision(NIBBLETYPE a_RailMeta);
|
||||||
|
/** Tests if a solid block is at a specific offset of the minecart position */
|
||||||
|
bool IsSolidBlockAtOffset(int a_XOffset, int a_YOffset, int a_ZOffset);
|
||||||
/** Tests if this mincecart's bounding box is intersecting another entity's bounding box (collision) and pushes mincecart away if necessary */
|
/** Tests if this mincecart's bounding box is intersecting another entity's bounding box (collision) and pushes mincecart away if necessary */
|
||||||
bool TestEntityCollision(NIBBLETYPE a_RailMeta);
|
bool TestEntityCollision(NIBBLETYPE a_RailMeta);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user