1
0

Fix minecart deceleration (#4059)

This commit is contained in:
peterbell10 2017-10-21 17:53:24 +01:00 committed by Alexander Harkness
parent f657193f45
commit 744cdb726d
2 changed files with 48 additions and 32 deletions

View File

@ -238,12 +238,12 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::millisecon
if (GetSpeedZ() > 0) if (GetSpeedZ() > 0)
{ {
// Going SOUTH, slow down // Going SOUTH, slow down
AddSpeedZ(-0.1); ApplyAcceleration({ 0.0, 0.0, 1.0 }, -0.1);
} }
else else
{ {
// Going NORTH, slow down // Going NORTH, slow down
AddSpeedZ(0.1); ApplyAcceleration({ 0.0, 0.0, -1.0 }, -0.1);
} }
} }
break; break;
@ -265,11 +265,11 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::millisecon
{ {
if (GetSpeedX() > 0) if (GetSpeedX() > 0)
{ {
AddSpeedX(-0.1); ApplyAcceleration({ 1.0, 0.0, 0.0 }, -0.1);
} }
else else
{ {
AddSpeedX(0.1); ApplyAcceleration({ -1.0, 0.0, 0.0 }, -0.1);
} }
} }
break; break;
@ -405,16 +405,9 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::millisecon
void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
{ {
// Initialise to 'slow down' values // If the rail is powered set to speed up else slow down.
int AccelDecelSpeed = -2; const bool IsRailPowered = ((a_RailMeta & 0x8) == 0x8);
int AccelDecelNegSpeed = 2; const double Acceleration = IsRailPowered ? 1.0 : -2.0;
if ((a_RailMeta & 0x8) == 0x8)
{
// Rail powered - set variables to 'speed up' values
AccelDecelSpeed = 1;
AccelDecelNegSpeed = -1;
}
switch (a_RailMeta & 0x07) switch (a_RailMeta & 0x07)
{ {
@ -435,26 +428,26 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
{ {
if (GetSpeedZ() > NO_SPEED) if (GetSpeedZ() > NO_SPEED)
{ {
AddSpeedZ(AccelDecelSpeed); ApplyAcceleration({ 0.0, 0.0, 1.0 }, Acceleration);
} }
else 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 // 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 IsBlockZP = IsSolidBlockAtOffset(0, 0, 1);
bool IsBlockZM = 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 // Only kick-start the minecart if a block is on one side, but not both
if (IsBlockZM && !IsBlockZP) if (IsBlockZM && !IsBlockZP)
{ {
AddSpeedZ(AccelDecelSpeed); ApplyAcceleration({ 0.0, 0.0, 1.0 }, Acceleration);
} }
else if (!IsBlockZM && IsBlockZP) else if (!IsBlockZM && IsBlockZP)
{ {
AddSpeedZ(AccelDecelNegSpeed); ApplyAcceleration({ 0.0, 0.0, -1.0 }, Acceleration);
} }
} }
break; break;
@ -476,26 +469,26 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
{ {
if (GetSpeedX() > NO_SPEED) if (GetSpeedX() > NO_SPEED)
{ {
AddSpeedX(AccelDecelSpeed); ApplyAcceleration({ 1.0, 0.0, 0.0 }, Acceleration);
} }
else 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 // 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 IsBlockXP = IsSolidBlockAtOffset(1, 0, 0);
bool IsBlockXM = 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 // Only kick-start the minecart if a block is on one side, but not both
if (IsBlockXM && !IsBlockXP) if (IsBlockXM && !IsBlockXP)
{ {
AddSpeedX(AccelDecelSpeed); ApplyAcceleration({ 1.0, 0.0, 0.0 }, Acceleration);
} }
else if (!IsBlockXM && IsBlockXP) else if (!IsBlockXM && IsBlockXP)
{ {
AddSpeedX(AccelDecelNegSpeed); ApplyAcceleration({ -1.0, 0.0, 0.0 }, Acceleration);
} }
} }
break; break;
@ -507,12 +500,12 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
if (GetSpeedX() >= NO_SPEED) if (GetSpeedX() >= NO_SPEED)
{ {
AddSpeedX(AccelDecelSpeed); ApplyAcceleration({ 1.0, 0.0, 0.0 }, Acceleration);
SetSpeedY(-GetSpeedX()); SetSpeedY(-GetSpeedX());
} }
else else
{ {
AddSpeedX(AccelDecelNegSpeed); ApplyAcceleration({ -1.0, 0.0, 0.0 }, Acceleration);
SetSpeedY(-GetSpeedX()); SetSpeedY(-GetSpeedX());
} }
break; break;
@ -524,12 +517,12 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
if (GetSpeedX() > NO_SPEED) if (GetSpeedX() > NO_SPEED)
{ {
AddSpeedX(AccelDecelSpeed); ApplyAcceleration({ 1.0, 0.0, 0.0 }, Acceleration);
SetSpeedY(GetSpeedX()); SetSpeedY(GetSpeedX());
} }
else else
{ {
AddSpeedX(AccelDecelNegSpeed); ApplyAcceleration({ -1.0, 0.0, 0.0 }, Acceleration);
SetSpeedY(GetSpeedX()); SetSpeedY(GetSpeedX());
} }
break; break;
@ -541,12 +534,12 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
if (GetSpeedZ() >= NO_SPEED) if (GetSpeedZ() >= NO_SPEED)
{ {
AddSpeedZ(AccelDecelSpeed); ApplyAcceleration({ 0.0, 0.0, 1.0 }, Acceleration);
SetSpeedY(-GetSpeedZ()); SetSpeedY(-GetSpeedZ());
} }
else else
{ {
AddSpeedZ(AccelDecelNegSpeed); ApplyAcceleration({ 0.0, 0.0, -1.0 }, Acceleration);
SetSpeedY(-GetSpeedZ()); SetSpeedY(-GetSpeedZ());
} }
break; break;
@ -558,12 +551,12 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta)
if (GetSpeedZ() > NO_SPEED) if (GetSpeedZ() > NO_SPEED)
{ {
AddSpeedZ(AccelDecelSpeed); ApplyAcceleration({ 0.0, 0.0, 1.0 }, Acceleration);
SetSpeedY(GetSpeedZ()); SetSpeedY(GetSpeedZ());
} }
else else
{ {
AddSpeedZ(AccelDecelNegSpeed); ApplyAcceleration({ 0.0, 0.0, -1.0 }, Acceleration);
SetSpeedY(GetSpeedZ()); SetSpeedY(GetSpeedZ());
} }
break; 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) void cMinecart::DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
{ {
if (a_SpeedX > MAX_SPEED) if (a_SpeedX > MAX_SPEED)

View File

@ -51,6 +51,9 @@ protected:
Vector3i m_DetectorRailPosition; Vector3i m_DetectorRailPosition;
bool m_bIsOnDetectorRail; 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 // Overwrite to enforce speed limit
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override; virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override;