diff options
-rw-r--r-- | src/Entities/Minecart.cpp | 94 |
1 files changed, 92 insertions, 2 deletions
diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index d4eadc5d5..21c58fdba 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -871,11 +871,101 @@ bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) return true; } case E_META_RAIL_CURVED_ZM_XM: + case E_META_RAIL_CURVED_ZP_XP: + { + Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); + + // Prevent division by small numbers + if (abs(Distance.z) < 0.001) + { + Distance.z = 0.001; + } + + /* Check to which side the minecart is to be pushed. + Let's consider a z-x-coordinate system where the minecart is the center (0/0). + The minecart moves along the line x = -z, the perpendicular line to this is x = z. + In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ + if ( + ((Distance.z > 0) && ((Distance.x / Distance.z) >= 1)) || + ((Distance.z < 0) && ((Distance.x / Distance.z) <= 1)) + ) + { + // Moving -X +Z + if ((-GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + { + // ~ SpeedX >= 0 Immobile or not moving in the "right" direction. Give it a bump! + AddSpeedX(-4 / sqrt(2)); + AddSpeedZ(4 / sqrt(2)); + } + else + { + // ~ SpeedX < 0 Moving in the "right" direction. Only accelerate it a bit. + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + } + } + else if ((GetSpeedX() * 0.4 / sqrt(2)) < 0.01) + { + // Moving +X -Z + // ~ SpeedX <= 0 Immobile or not moving in the "right" direction + AddSpeedX(4 / sqrt(2)); + AddSpeedZ(-4 / sqrt(2)); + } + else + { + // ~ SpeedX > 0 Moving in the "right" direction + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + } + break; + } case E_META_RAIL_CURVED_ZM_XP: case E_META_RAIL_CURVED_ZP_XM: - case E_META_RAIL_CURVED_ZP_XP: { - // TODO - simply can't be bothered right now + Vector3d Distance = MinecartCollisionCallback.GetCollidedEntityPosition() - Vector3d(GetPosX(), 0, GetPosZ()); + + // Prevent division by small numbers + if (abs(Distance.z) < 0.001) + { + Distance.z = 0.001; + } + + /* Check to which side the minecart is to be pushed. + Let's consider a z-x-coordinate system where the minecart is the center (0/0). + The minecart moves along the line x = z, the perpendicular line to this is x = -z. + In order to decide to which side the minecart is to be pushed, it must be checked on what side of the perpendicular line the pushing entity is located. */ + if ( + ((Distance.z > 0) && ((Distance.x / Distance.z) <= -1)) || + ((Distance.z < 0) && ((Distance.x / Distance.z) >= -1)) + ) + { + // Moving +X +Z + if ((GetSpeedX() * 0.4) < 0.01) + { + // ~ SpeedX <= 0 Immobile or not moving in the "right" direction + AddSpeedX(4 / sqrt(2)); + AddSpeedZ(4 / sqrt(2)); + } + else + { + // ~ SpeedX > 0 Moving in the "right" direction + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + } + } + else if ((-GetSpeedX() * 0.4) < 0.01) + { + // Moving -X -Z + // ~ SpeedX >= 0 Immobile or not moving in the "right" direction + AddSpeedX(-4 / sqrt(2)); + AddSpeedZ(-4 / sqrt(2)); + } + else + { + // ~ SpeedX < 0 Moving in the "right" direction + SetSpeedX(GetSpeedX() * 0.4 / sqrt(2)); + SetSpeedZ(GetSpeedZ() * 0.4 / sqrt(2)); + } break; } default: break; |