From 744cdb726d1a036c29a8038775ab2e758c25a087 Mon Sep 17 00:00:00 2001 From: peterbell10 Date: Sat, 21 Oct 2017 17:53:24 +0100 Subject: Fix minecart deceleration (#4059) --- src/Entities/Minecart.cpp | 77 +++++++++++++++++++++++++++-------------------- src/Entities/Minecart.h | 3 ++ 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 8921f8894..7c5ca49ce 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -238,12 +238,12 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::millisecon if (GetSpeedZ() > 0) { // Going SOUTH, slow down - AddSpeedZ(-0.1); + ApplyAcceleration({ 0.0, 0.0, 1.0 }, -0.1); } else { // Going NORTH, slow down - AddSpeedZ(0.1); + ApplyAcceleration({ 0.0, 0.0, -1.0 }, -0.1); } } break; @@ -265,11 +265,11 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::millisecon { if (GetSpeedX() > 0) { - AddSpeedX(-0.1); + ApplyAcceleration({ 1.0, 0.0, 0.0 }, -0.1); } else { - AddSpeedX(0.1); + ApplyAcceleration({ -1.0, 0.0, 0.0 }, -0.1); } } break; @@ -405,16 +405,9 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::millisecon void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) { - // Initialise to 'slow down' values - int AccelDecelSpeed = -2; - int AccelDecelNegSpeed = 2; - - if ((a_RailMeta & 0x8) == 0x8) - { - // Rail powered - set variables to 'speed up' values - AccelDecelSpeed = 1; - AccelDecelNegSpeed = -1; - } + // If the rail is powered set to speed up else slow down. + const bool IsRailPowered = ((a_RailMeta & 0x8) == 0x8); + const double Acceleration = IsRailPowered ? 1.0 : -2.0; switch (a_RailMeta & 0x07) { @@ -435,26 +428,26 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) { if (GetSpeedZ() > NO_SPEED) { - AddSpeedZ(AccelDecelSpeed); + ApplyAcceleration({ 0.0, 0.0, 1.0 }, Acceleration); } else { - AddSpeedZ(AccelDecelNegSpeed); + ApplyAcceleration({ 0.0, 0.0, -1.0 }, Acceleration); } } // If rail is powered check for nearby blocks that could kick-start the minecart - else if ((a_RailMeta & 0x8) == 0x8) + else if (IsRailPowered) { 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); + ApplyAcceleration({ 0.0, 0.0, 1.0 }, Acceleration); } else if (!IsBlockZM && IsBlockZP) { - AddSpeedZ(AccelDecelNegSpeed); + ApplyAcceleration({ 0.0, 0.0, -1.0 }, Acceleration); } } break; @@ -476,26 +469,26 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) { if (GetSpeedX() > NO_SPEED) { - AddSpeedX(AccelDecelSpeed); + ApplyAcceleration({ 1.0, 0.0, 0.0 }, Acceleration); } else { - AddSpeedX(AccelDecelNegSpeed); + ApplyAcceleration({ -1.0, 0.0, 0.0 }, Acceleration); } } // If rail is powered check for nearby blocks that could kick-start the minecart - else if ((a_RailMeta & 0x8) == 0x8) + else if (IsRailPowered) { 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); + ApplyAcceleration({ 1.0, 0.0, 0.0 }, Acceleration); } else if (!IsBlockXM && IsBlockXP) { - AddSpeedX(AccelDecelNegSpeed); + ApplyAcceleration({ -1.0, 0.0, 0.0 }, Acceleration); } } break; @@ -507,12 +500,12 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) if (GetSpeedX() >= NO_SPEED) { - AddSpeedX(AccelDecelSpeed); + ApplyAcceleration({ 1.0, 0.0, 0.0 }, Acceleration); SetSpeedY(-GetSpeedX()); } else { - AddSpeedX(AccelDecelNegSpeed); + ApplyAcceleration({ -1.0, 0.0, 0.0 }, Acceleration); SetSpeedY(-GetSpeedX()); } break; @@ -524,12 +517,12 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) if (GetSpeedX() > NO_SPEED) { - AddSpeedX(AccelDecelSpeed); + ApplyAcceleration({ 1.0, 0.0, 0.0 }, Acceleration); SetSpeedY(GetSpeedX()); } else { - AddSpeedX(AccelDecelNegSpeed); + ApplyAcceleration({ -1.0, 0.0, 0.0 }, Acceleration); SetSpeedY(GetSpeedX()); } break; @@ -541,12 +534,12 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) if (GetSpeedZ() >= NO_SPEED) { - AddSpeedZ(AccelDecelSpeed); + ApplyAcceleration({ 0.0, 0.0, 1.0 }, Acceleration); SetSpeedY(-GetSpeedZ()); } else { - AddSpeedZ(AccelDecelNegSpeed); + ApplyAcceleration({ 0.0, 0.0, -1.0 }, Acceleration); SetSpeedY(-GetSpeedZ()); } break; @@ -558,12 +551,12 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) if (GetSpeedZ() > NO_SPEED) { - AddSpeedZ(AccelDecelSpeed); + ApplyAcceleration({ 0.0, 0.0, 1.0 }, Acceleration); SetSpeedY(GetSpeedZ()); } else { - AddSpeedZ(AccelDecelNegSpeed); + ApplyAcceleration({ 0.0, 0.0, -1.0 }, Acceleration); SetSpeedY(GetSpeedZ()); } break; @@ -1098,6 +1091,26 @@ bool cMinecart::DoTakeDamage(TakeDamageInfo & TDI) +void cMinecart::ApplyAcceleration(Vector3d a_ForwardDirection, double a_Acceleration) +{ + double CurSpeed = GetSpeed().Dot(a_ForwardDirection); + double NewSpeed = CurSpeed + a_Acceleration; + + if (NewSpeed < 0.0) + { + // Prevent deceleration from turning the minecart around. + NewSpeed = 0.0; + } + + auto Acceleration = a_ForwardDirection * (NewSpeed - CurSpeed); + + AddSpeed(Acceleration); +} + + + + + void cMinecart::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) { if (a_SpeedX > MAX_SPEED) diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index f1f499328..99885faf9 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -51,6 +51,9 @@ protected: Vector3i m_DetectorRailPosition; bool m_bIsOnDetectorRail; + /** Applies an acceleration to the minecart parallel to a_ForwardDirection but without allowing backward speed. */ + void ApplyAcceleration(Vector3d a_ForwardDirection, double a_Acceleration); + // Overwrite to enforce speed limit virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override; -- cgit v1.2.3