From f1f86c46d37051b16a70bbc3c0c663873ccdf2eb Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 27 Aug 2013 20:38:11 +0100 Subject: Preliminary Minecart physics handling [SEE DESC] This commit includes physics handling for the following scenarios: Flat rails in orientations [N, S, W, E] Ascending/descending rails in orientations [N, S, W, E] Powered rails are NOT handled (they don't respond to redstone). Curved rails are NOT handled (I haven't figured out how to do them :P) Please note that I have not tried to emulate vanilla behaviour because of a lack of knowledge on velocity unites/C++. We can say it's a feature or something. :P --- source/Entities/Entity.h | 6 +- source/Entities/Minecart.cpp | 197 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 199 insertions(+), 4 deletions(-) (limited to 'source/Entities') diff --git a/source/Entities/Entity.h b/source/Entities/Entity.h index 820405cb9..7ae70b8cf 100644 --- a/source/Entities/Entity.h +++ b/source/Entities/Entity.h @@ -351,6 +351,9 @@ protected: bool m_bOnGround; float m_Gravity; + + // Measured in Kilograms (Kg) + double m_Mass; // Last Position. double m_LastPosX, m_LastPosY, m_LastPosZ; @@ -399,9 +402,6 @@ private: // Measured in meter / second Vector3d m_WaterSpeed; - // Measured in Kilograms (Kg) - double m_Mass; - /// Width of the entity, in the XZ plane. Since entities are represented as cylinders, this is more of a diameter. double m_Width; diff --git a/source/Entities/Minecart.cpp b/source/Entities/Minecart.cpp index 3e6069237..20811580a 100644 --- a/source/Entities/Minecart.cpp +++ b/source/Entities/Minecart.cpp @@ -2,6 +2,7 @@ // Minecart.cpp // Implements the cMinecart class representing a minecart in the world +// Indiana Jones! #include "Globals.h" #include "Minecart.h" @@ -17,6 +18,7 @@ cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) : super(etMinecart, a_X, a_Y, a_Z, 0.98, 0.7), m_Payload(a_Payload) { + m_Mass = 20.f; } @@ -59,9 +61,202 @@ void cMinecart::SpawnOn(cClientHandle & a_ClientHandle) +enum ENUM_RAIL_DIRECTIONS +{ + E_RAIL_NORTH_SOUTH = 0, + E_RAIL_EAST_WEST = 1, + E_RAIL_ASCEND_EAST = 2, + E_RAIL_ASCEND_WEST = 3, + E_RAIL_ASCEND_NORTH = 4, + E_RAIL_ASCEND_SOUTH = 5, + E_RAIL_CURVED_SOUTH_EAST = 6, + E_RAIL_CURVED_SOUTH_WEST = 7, + E_RAIL_CURVED_NORTH_WEST = 8, + E_RAIL_CURVED_NORTH_EAST = 9, +} ; + + + + + void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) { - // TODO: the physics + /* + NOTE: Please bear in mind that taking away from negatives make them even more negative, + adding to negatives make them positive, etc. Also remember that - North is -Z, South +Z, West -X, and East +Z + */ + + super::Tick(a_Dt, a_Chunk); + + BLOCKTYPE BelowType; + NIBBLETYPE BelowMeta; + double SpeedX = GetSpeedX(), SpeedY = GetSpeedY(), SpeedZ = GetSpeedZ(); // Get current speed + + // Get block type & meta below the cart + GetWorld()->GetBlockTypeMeta(floor(GetPosX()), floor(GetPosY() -1 ), floor(GetPosZ()), BelowType, BelowMeta); + + if ((BelowType == E_BLOCK_RAIL) || (BelowType == E_BLOCK_DETECTOR_RAIL) || (BelowType == E_BLOCK_ACTIVATOR_RAIL)) + { + switch (BelowMeta) + { + + case E_RAIL_NORTH_SOUTH: + { + SpeedY = 0; // Don't move vertically as on ground + + // Set Y as current Y rounded up to bypass friction + // TODO: this causes positioning mismatches on the client, but Entity physics insists on friction! + SetPosY(ceil(GetPosY()) + 0.05); + + if (SpeedZ != 0) // Don't do anything if cart is stationary + { + if (SpeedZ > 0) + { + // Going SOUTH, slow down + SpeedZ = SpeedZ - 0.05; + } + else + { + // Going NORTH, slow down + SpeedZ = SpeedZ + 0.05; + } + } + break; + } + + case E_RAIL_EAST_WEST: + { + SpeedY = 0; + SetPosY(ceil(GetPosY()) + 0.05); + + if (SpeedX != 0) + { + if (SpeedX > 0) + { + SpeedX = SpeedX - 0.05; + } + else + { + SpeedX = SpeedX + 0.05; + } + } + break; + } + + case E_RAIL_ASCEND_NORTH: + { + if (SpeedZ >= 0) + { + // SpeedZ POSITIVE, going SOUTH + if (SpeedZ <= 6) // Speed limit of 6 SOUTH (m/s??) + { + SpeedZ = SpeedZ + 1; // Speed up + SpeedY = (0 - SpeedZ); // Downward movement is negative (0 minus positive numbers is negative) + } + else + { + SpeedZ = 6; // Enforce speed limit + SpeedY = (0 - SpeedZ); + } + } + else + { + // SpeedZ NEGATIVE, going NORTH + SpeedZ = SpeedZ + 0.1; // Slow down + SpeedY = (0 - SpeedZ); // Upward movement is positive (0 minus negative number is positive number) + } + break; + } + + case E_RAIL_ASCEND_SOUTH: + { + if (SpeedX > 0) + { + // SpeedZ POSITIVE, going SOUTH + SpeedZ = SpeedZ - 0.1; // Slow down + SpeedY = SpeedZ; // Upward movement positive + } + else + { + if (SpeedZ >= -6) // Speed limit of 6 WEST (m/s??) + { + // SpeedZ NEGATIVE, going NORTH + SpeedZ = SpeedZ - 1; // Speed up + SpeedY = SpeedZ; // Downward movement negative + } + else + { + SpeedZ = 6; // Enforce speed limit + SpeedY = SpeedZ; + } + } + break; + } + + case E_RAIL_ASCEND_WEST: + { + if (SpeedX >= 0) + { + if (SpeedX <= 6) + { + SpeedX = SpeedX + 1; + SpeedY = (0 - SpeedX); + } + else + { + SpeedX = 6; + SpeedY = (0 - SpeedX); + } + } + else + { + SpeedX = SpeedX + 0.1; + SpeedY = (0 - SpeedX); + } + break; + } + + case E_RAIL_ASCEND_EAST: + { + if (SpeedX > 0) + { + SpeedX = SpeedX - 0.1; + SpeedY = SpeedX; + } + else + { + if (SpeedX >= -6) + { + SpeedX = SpeedX - 1; + SpeedY = SpeedX; + } + else + { + SpeedX = -6; + SpeedY = SpeedX; + } + } + break; + } + + default: + { + ASSERT(!"Unhandled rail meta!"); + break; + } + + } + } + + // Set speed to speed variables + SetSpeedX(SpeedX); + SetSpeedY(SpeedY); + SetSpeedZ(SpeedZ); + + // Pass to physics handlers in Entity.cpp and broadcast position to client + HandlePhysics(a_Dt, a_Chunk); + BroadcastMovementUpdate(); + } -- cgit v1.2.3 From 1e910022291df03d5bc92b88d6a526e1bc0f095e Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 28 Aug 2013 22:13:27 +0100 Subject: Fixed Minecart spawning issues Now you can have everything! --- source/Entities/Minecart.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source/Entities') diff --git a/source/Entities/Minecart.cpp b/source/Entities/Minecart.cpp index 20811580a..c484d8763 100644 --- a/source/Entities/Minecart.cpp +++ b/source/Entities/Minecart.cpp @@ -18,7 +18,8 @@ cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) : super(etMinecart, a_X, a_Y, a_Z, 0.98, 0.7), m_Payload(a_Payload) { - m_Mass = 20.f; + SetMass(20.f); + SetMaxHealth(6); } @@ -40,21 +41,21 @@ bool cMinecart::Initialize(cWorld * a_World) void cMinecart::SpawnOn(cClientHandle & a_ClientHandle) { - char Type = 0; - switch (m_Payload) //Wiki.vg is outdated on this!! + char TypeType = 0; + switch (m_Payload) { - case mpNone: Type = 9; break; //? - case mpChest: Type = 10; break; - case mpFurnace: Type = 11; break; //? - case mpTNT: Type = 12; break; //? - case mpHopper: Type = 13; break; //? + case mpNone: TypeType = 0; break; + case mpChest: TypeType = 1; break; + case mpFurnace: TypeType = 2; break; + case mpTNT: TypeType = 3; break; + case mpHopper: TypeType = 5; break; default: { ASSERT(!"Unknown payload, cannot spawn on client"); return; } } - a_ClientHandle.SendSpawnVehicle(*this, Type); + a_ClientHandle.SendSpawnVehicle(*this, 10, TypeType); // 10 = Minecarts, TypeType = What type of Minecart } -- cgit v1.2.3 From 7056992d0d99fde627e00c5d7f524cad0a70073d Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 Aug 2013 13:47:22 +0100 Subject: Implemented xoft's suggestions [SEE DESC] Rail metas are now in BlockID and exported to LUA Minecart now does a SetMass, instead of m_Mass Minecarts use SubType instead of TypeType --- source/Entities/Entity.h | 6 +++--- source/Entities/Minecart.cpp | 46 ++++++++++++++------------------------------ 2 files changed, 17 insertions(+), 35 deletions(-) (limited to 'source/Entities') diff --git a/source/Entities/Entity.h b/source/Entities/Entity.h index 7ae70b8cf..119cb2fe5 100644 --- a/source/Entities/Entity.h +++ b/source/Entities/Entity.h @@ -352,9 +352,6 @@ protected: bool m_bOnGround; float m_Gravity; - // Measured in Kilograms (Kg) - double m_Mass; - // Last Position. double m_LastPosX, m_LastPosY, m_LastPosZ; @@ -402,6 +399,9 @@ private: // Measured in meter / second Vector3d m_WaterSpeed; + // Measured in Kilograms (Kg) + double m_Mass; + /// Width of the entity, in the XZ plane. Since entities are represented as cylinders, this is more of a diameter. double m_Width; diff --git a/source/Entities/Minecart.cpp b/source/Entities/Minecart.cpp index c484d8763..556454795 100644 --- a/source/Entities/Minecart.cpp +++ b/source/Entities/Minecart.cpp @@ -41,50 +41,32 @@ bool cMinecart::Initialize(cWorld * a_World) void cMinecart::SpawnOn(cClientHandle & a_ClientHandle) { - char TypeType = 0; + char SubType = 0; switch (m_Payload) { - case mpNone: TypeType = 0; break; - case mpChest: TypeType = 1; break; - case mpFurnace: TypeType = 2; break; - case mpTNT: TypeType = 3; break; - case mpHopper: TypeType = 5; break; + case mpNone: SubType = 0; break; + case mpChest: SubType = 1; break; + case mpFurnace: SubType = 2; break; + case mpTNT: SubType = 3; break; + case mpHopper: SubType = 5; break; default: { ASSERT(!"Unknown payload, cannot spawn on client"); return; } } - a_ClientHandle.SendSpawnVehicle(*this, 10, TypeType); // 10 = Minecarts, TypeType = What type of Minecart + a_ClientHandle.SendSpawnVehicle(*this, 10, SubType); // 10 = Minecarts, TypeType = What type of Minecart } -enum ENUM_RAIL_DIRECTIONS -{ - E_RAIL_NORTH_SOUTH = 0, - E_RAIL_EAST_WEST = 1, - E_RAIL_ASCEND_EAST = 2, - E_RAIL_ASCEND_WEST = 3, - E_RAIL_ASCEND_NORTH = 4, - E_RAIL_ASCEND_SOUTH = 5, - E_RAIL_CURVED_SOUTH_EAST = 6, - E_RAIL_CURVED_SOUTH_WEST = 7, - E_RAIL_CURVED_NORTH_WEST = 8, - E_RAIL_CURVED_NORTH_EAST = 9, -} ; - - - - - void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) { /* NOTE: Please bear in mind that taking away from negatives make them even more negative, - adding to negatives make them positive, etc. Also remember that - North is -Z, South +Z, West -X, and East +Z + adding to negatives make them positive, etc. */ super::Tick(a_Dt, a_Chunk); @@ -101,7 +83,7 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) switch (BelowMeta) { - case E_RAIL_NORTH_SOUTH: + case E_RAIL_ZM_ZP: { SpeedY = 0; // Don't move vertically as on ground @@ -125,7 +107,7 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_EAST_WEST: + case E_RAIL_XM_XP: { SpeedY = 0; SetPosY(ceil(GetPosY()) + 0.05); @@ -144,7 +126,7 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_ASCEND_NORTH: + case E_RAIL_ASCEND_ZM: { if (SpeedZ >= 0) { @@ -169,7 +151,7 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_ASCEND_SOUTH: + case E_RAIL_ASCEND_ZP: { if (SpeedX > 0) { @@ -194,7 +176,7 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_ASCEND_WEST: + case E_RAIL_ASCEND_XM: { if (SpeedX >= 0) { @@ -217,7 +199,7 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_ASCEND_EAST: + case E_RAIL_ASCEND_XP: { if (SpeedX > 0) { -- cgit v1.2.3 From 9f59b9a0934532a0d8a047c3e3598f8c817bcdc1 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 Aug 2013 14:00:39 +0100 Subject: Corrected comment TypeType --- source/Entities/Minecart.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/Entities') diff --git a/source/Entities/Minecart.cpp b/source/Entities/Minecart.cpp index 556454795..40b676193 100644 --- a/source/Entities/Minecart.cpp +++ b/source/Entities/Minecart.cpp @@ -55,7 +55,7 @@ void cMinecart::SpawnOn(cClientHandle & a_ClientHandle) return; } } - a_ClientHandle.SendSpawnVehicle(*this, 10, SubType); // 10 = Minecarts, TypeType = What type of Minecart + a_ClientHandle.SendSpawnVehicle(*this, 10, SubType); // 10 = Minecarts, SubType = What type of Minecart } -- cgit v1.2.3 From acaae7a11e81e93fb0b5288ef830052e10a3d8f5 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 29 Aug 2013 15:25:12 +0100 Subject: Physics enhancements Minecarts no longer glitch on flat rails Improved acceleration, speed limit, and stopping --- source/Entities/Entity.cpp | 21 +++++++++++++++------ source/Entities/Minecart.cpp | 45 ++++++++++++++++++++++---------------------- 2 files changed, 37 insertions(+), 29 deletions(-) (limited to 'source/Entities') diff --git a/source/Entities/Entity.cpp b/source/Entities/Entity.cpp index 19a65ef4e..b9810aabb 100644 --- a/source/Entities/Entity.cpp +++ b/source/Entities/Entity.cpp @@ -499,6 +499,7 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) int RelBlockX = BlockX - (NextChunk->GetPosX() * cChunkDef::Width); int RelBlockZ = BlockZ - (NextChunk->GetPosZ() * cChunkDef::Width); BLOCKTYPE BlockIn = NextChunk->GetBlock( RelBlockX, BlockY, RelBlockZ ); + BLOCKTYPE BlockBelow = NextChunk->GetBlock( RelBlockX, BlockY - 1, RelBlockZ ); if (!g_BlockIsSolid[BlockIn]) // Making sure we are not inside a solid block { if (m_bOnGround) // check if it's still on the ground @@ -540,13 +541,21 @@ void cEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk) } else { - //Friction - if (NextSpeed.SqrLength() > 0.0004f) + if ( + (BlockBelow != E_BLOCK_RAIL) && + (BlockBelow != E_BLOCK_DETECTOR_RAIL) && + (BlockBelow != E_BLOCK_POWERED_RAIL) && + (BlockBelow != E_BLOCK_ACTIVATOR_RAIL) + ) { - NextSpeed.x *= 0.7f/(1+a_Dt); - if ( fabs(NextSpeed.x) < 0.05 ) NextSpeed.x = 0; - NextSpeed.z *= 0.7f/(1+a_Dt); - if ( fabs(NextSpeed.z) < 0.05 ) NextSpeed.z = 0; + //Friction + if (NextSpeed.SqrLength() > 0.0004f) + { + NextSpeed.x *= 0.7f/(1+a_Dt); + if ( fabs(NextSpeed.x) < 0.05 ) NextSpeed.x = 0; + NextSpeed.z *= 0.7f/(1+a_Dt); + if ( fabs(NextSpeed.z) < 0.05 ) NextSpeed.z = 0; + } } } diff --git a/source/Entities/Minecart.cpp b/source/Entities/Minecart.cpp index 40b676193..a148886a6 100644 --- a/source/Entities/Minecart.cpp +++ b/source/Entities/Minecart.cpp @@ -88,20 +88,19 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) SpeedY = 0; // Don't move vertically as on ground // Set Y as current Y rounded up to bypass friction - // TODO: this causes positioning mismatches on the client, but Entity physics insists on friction! - SetPosY(ceil(GetPosY()) + 0.05); + SetPosY(floor(GetPosY())); if (SpeedZ != 0) // Don't do anything if cart is stationary { if (SpeedZ > 0) { // Going SOUTH, slow down - SpeedZ = SpeedZ - 0.05; + SpeedZ = SpeedZ - 0.1; } else { // Going NORTH, slow down - SpeedZ = SpeedZ + 0.05; + SpeedZ = SpeedZ + 0.1; } } break; @@ -110,17 +109,17 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) case E_RAIL_XM_XP: { SpeedY = 0; - SetPosY(ceil(GetPosY()) + 0.05); + SetPosY(floor(GetPosY())); if (SpeedX != 0) { if (SpeedX > 0) { - SpeedX = SpeedX - 0.05; + SpeedX = SpeedX - 0.1; } else { - SpeedX = SpeedX + 0.05; + SpeedX = SpeedX + 0.1; } } break; @@ -131,21 +130,21 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) if (SpeedZ >= 0) { // SpeedZ POSITIVE, going SOUTH - if (SpeedZ <= 6) // Speed limit of 6 SOUTH (m/s??) + if (SpeedZ <= 8) // Speed limit of 8 SOUTH (m/s??) { - SpeedZ = SpeedZ + 1; // Speed up + SpeedZ = SpeedZ + 0.5; // Speed up SpeedY = (0 - SpeedZ); // Downward movement is negative (0 minus positive numbers is negative) } else { - SpeedZ = 6; // Enforce speed limit + SpeedZ = 8; // Enforce speed limit SpeedY = (0 - SpeedZ); } } else { // SpeedZ NEGATIVE, going NORTH - SpeedZ = SpeedZ + 0.1; // Slow down + SpeedZ = SpeedZ + 0.6; // Slow down SpeedY = (0 - SpeedZ); // Upward movement is positive (0 minus negative number is positive number) } break; @@ -156,20 +155,20 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) if (SpeedX > 0) { // SpeedZ POSITIVE, going SOUTH - SpeedZ = SpeedZ - 0.1; // Slow down + SpeedZ = SpeedZ - 0.6; // Slow down SpeedY = SpeedZ; // Upward movement positive } else { - if (SpeedZ >= -6) // Speed limit of 6 WEST (m/s??) + if (SpeedZ >= -8) // Speed limit of 8 WEST (m/s??) { // SpeedZ NEGATIVE, going NORTH - SpeedZ = SpeedZ - 1; // Speed up + SpeedZ = SpeedZ - 0.5; // Speed up SpeedY = SpeedZ; // Downward movement negative } else { - SpeedZ = 6; // Enforce speed limit + SpeedZ = 8; // Enforce speed limit SpeedY = SpeedZ; } } @@ -180,20 +179,20 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) { if (SpeedX >= 0) { - if (SpeedX <= 6) + if (SpeedX <= 8) { - SpeedX = SpeedX + 1; + SpeedX = SpeedX + 0.5; SpeedY = (0 - SpeedX); } else { - SpeedX = 6; + SpeedX = 8; SpeedY = (0 - SpeedX); } } else { - SpeedX = SpeedX + 0.1; + SpeedX = SpeedX + 0.6; SpeedY = (0 - SpeedX); } break; @@ -203,19 +202,19 @@ void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) { if (SpeedX > 0) { - SpeedX = SpeedX - 0.1; + SpeedX = SpeedX - 0.6; SpeedY = SpeedX; } else { - if (SpeedX >= -6) + if (SpeedX >= -8) { - SpeedX = SpeedX - 1; + SpeedX = SpeedX - 0.5; SpeedY = SpeedX; } else { - SpeedX = -6; + SpeedX = -8; SpeedY = SpeedX; } } -- cgit v1.2.3 From b5c63d8fc50d9f8ff179988a9a14010de89f5d75 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 2 Sep 2013 12:01:49 +0100 Subject: Minecart enhancements [SEE DESC] Curved rails. Better physics. Better code as improved by xoft. Stuff. --- source/Entities/Minecart.cpp | 350 +++++++++++++++++++++++++++++-------------- source/Entities/Minecart.h | 5 +- 2 files changed, 242 insertions(+), 113 deletions(-) (limited to 'source/Entities') diff --git a/source/Entities/Minecart.cpp b/source/Entities/Minecart.cpp index a148886a6..9a92df38e 100644 --- a/source/Entities/Minecart.cpp +++ b/source/Entities/Minecart.cpp @@ -20,6 +20,7 @@ cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) : { SetMass(20.f); SetMaxHealth(6); + SetHealth(6); } @@ -62,183 +63,308 @@ void cMinecart::SpawnOn(cClientHandle & a_ClientHandle) -void cMinecart::Tick(float a_Dt, cChunk & a_Chunk) +void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk) { + if ((GetPosY() > 0) && (GetPosY() < cChunkDef::Height)) + { + BLOCKTYPE BelowType = GetWorld()->GetBlock(floor(GetPosX()), floor(GetPosY() -1 ), floor(GetPosZ())); + + if ( + (BelowType == E_BLOCK_RAIL) || + (BelowType == E_BLOCK_POWERED_RAIL) || + (BelowType == E_BLOCK_DETECTOR_RAIL) || + (BelowType == E_BLOCK_ACTIVATOR_RAIL) + ) + { + HandleRailPhysics(a_Dt, a_Chunk); + } + else + { + super::HandlePhysics(a_Dt, a_Chunk); + BroadcastMovementUpdate(); + } + } + else + { + super::HandlePhysics(a_Dt, a_Chunk); + BroadcastMovementUpdate(); + } +} + + + + + +static const double MAX_SPEED = 8; +static const double MAX_SPEED_NEGATIVE = (0 - MAX_SPEED); +void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) +{ + + super::HandlePhysics(a_Dt, a_Chunk); // Main physics handling + /* NOTE: Please bear in mind that taking away from negatives make them even more negative, adding to negatives make them positive, etc. */ - super::Tick(a_Dt, a_Chunk); - - BLOCKTYPE BelowType; - NIBBLETYPE BelowMeta; + // Get block meta below the cart + NIBBLETYPE BelowMeta = GetWorld()->GetBlockMeta(floor(GetPosX()), floor(GetPosY() -1 ), floor(GetPosZ())); double SpeedX = GetSpeedX(), SpeedY = GetSpeedY(), SpeedZ = GetSpeedZ(); // Get current speed - - // Get block type & meta below the cart - GetWorld()->GetBlockTypeMeta(floor(GetPosX()), floor(GetPosY() -1 ), floor(GetPosZ()), BelowType, BelowMeta); - - if ((BelowType == E_BLOCK_RAIL) || (BelowType == E_BLOCK_DETECTOR_RAIL) || (BelowType == E_BLOCK_ACTIVATOR_RAIL)) + + switch (BelowMeta) { - switch (BelowMeta) + case E_RAIL_ZM_ZP: // NORTHSOUTH { - - case E_RAIL_ZM_ZP: + SetRotation(270); + SpeedY = 0; // Don't move vertically as on ground + SpeedX = 0; // Correct diagonal movement from curved rails + + // Set Y as current Y rounded up to bypass friction + SetPosY(floor(GetPosY())); + + if (SpeedZ != 0) // Don't do anything if cart is stationary { - SpeedY = 0; // Don't move vertically as on ground - - // Set Y as current Y rounded up to bypass friction - SetPosY(floor(GetPosY())); - - if (SpeedZ != 0) // Don't do anything if cart is stationary + if (SpeedZ > 0) + { + // Going SOUTH, slow down + SpeedZ = SpeedZ - 0.1; + } + else { - if (SpeedZ > 0) - { - // Going SOUTH, slow down - SpeedZ = SpeedZ - 0.1; - } - else - { - // Going NORTH, slow down - SpeedZ = SpeedZ + 0.1; - } + // Going NORTH, slow down + SpeedZ = SpeedZ + 0.1; } - break; } + break; + } - case E_RAIL_XM_XP: - { - SpeedY = 0; - SetPosY(floor(GetPosY())); + case E_RAIL_XM_XP: // EASTWEST + { + SetRotation(180); + SpeedY = 0; + SpeedZ = 0; - if (SpeedX != 0) + SetPosY(floor(GetPosY())); + + if (SpeedX != 0) + { + if (SpeedX > 0) { - if (SpeedX > 0) - { - SpeedX = SpeedX - 0.1; - } - else - { - SpeedX = SpeedX + 0.1; - } + SpeedX = SpeedX - 0.1; + } + else + { + SpeedX = SpeedX + 0.1; } - break; } + break; + } + + case E_RAIL_ASCEND_ZM: // ASCEND NORTH + { + SetRotation(270); + SetPosY(floor(GetPosY()) + 0.2); // It seems it doesn't work without levitation :/ + SpeedX = 0; - case E_RAIL_ASCEND_ZM: + if (SpeedZ >= 0) { - if (SpeedZ >= 0) + // SpeedZ POSITIVE, going SOUTH + if (SpeedZ <= MAX_SPEED) // Speed limit { - // SpeedZ POSITIVE, going SOUTH - if (SpeedZ <= 8) // Speed limit of 8 SOUTH (m/s??) - { - SpeedZ = SpeedZ + 0.5; // Speed up - SpeedY = (0 - SpeedZ); // Downward movement is negative (0 minus positive numbers is negative) - } - else - { - SpeedZ = 8; // Enforce speed limit - SpeedY = (0 - SpeedZ); - } + SpeedZ = SpeedZ + 0.5; // Speed up + SpeedY = (0 - SpeedZ); // Downward movement is negative (0 minus positive numbers is negative) } else { - // SpeedZ NEGATIVE, going NORTH - SpeedZ = SpeedZ + 0.6; // Slow down - SpeedY = (0 - SpeedZ); // Upward movement is positive (0 minus negative number is positive number) + SpeedZ = MAX_SPEED; // Enforce speed limit + SpeedY = (0 - SpeedZ); } - break; } + else + { + // SpeedZ NEGATIVE, going NORTH + SpeedZ = SpeedZ + 0.4; // Slow down + SpeedY = (0 - SpeedZ); // Upward movement is positive (0 minus negative number is positive number) + } + break; + } + + case E_RAIL_ASCEND_ZP: // ASCEND SOUTH + { + SetRotation(270); + SetPosY(floor(GetPosY()) + 0.2); + SpeedX = 0; - case E_RAIL_ASCEND_ZP: + if (SpeedZ > 0) { - if (SpeedX > 0) + // SpeedZ POSITIVE, going SOUTH + SpeedZ = SpeedZ - 0.4; // Slow down + SpeedY = SpeedZ; // Upward movement positive + } + else + { + if (SpeedZ >= MAX_SPEED_NEGATIVE) // Speed limit { - // SpeedZ POSITIVE, going SOUTH - SpeedZ = SpeedZ - 0.6; // Slow down - SpeedY = SpeedZ; // Upward movement positive + // SpeedZ NEGATIVE, going NORTH + SpeedZ = SpeedZ - 0.5; // Speed up + SpeedY = SpeedZ; // Downward movement negative } else { - if (SpeedZ >= -8) // Speed limit of 8 WEST (m/s??) - { - // SpeedZ NEGATIVE, going NORTH - SpeedZ = SpeedZ - 0.5; // Speed up - SpeedY = SpeedZ; // Downward movement negative - } - else - { - SpeedZ = 8; // Enforce speed limit - SpeedY = SpeedZ; - } + SpeedZ = MAX_SPEED_NEGATIVE; // Enforce speed limit + SpeedY = SpeedZ; } - break; } + break; + } + + case E_RAIL_ASCEND_XM: // ASCEND EAST + { + SetRotation(180); + SetPosY(floor(GetPosY()) + 0.2); + SpeedZ = 0; - case E_RAIL_ASCEND_XM: + if (SpeedX >= 0) { - if (SpeedX >= 0) + if (SpeedX <= MAX_SPEED) { - if (SpeedX <= 8) - { - SpeedX = SpeedX + 0.5; - SpeedY = (0 - SpeedX); - } - else - { - SpeedX = 8; - SpeedY = (0 - SpeedX); - } + SpeedX = SpeedX + 0.5; + SpeedY = (0 - SpeedX); } else { - SpeedX = SpeedX + 0.6; + SpeedX = MAX_SPEED; SpeedY = (0 - SpeedX); } - break; } + else + { + SpeedX = SpeedX + 0.4; + SpeedY = (0 - SpeedX); + } + break; + } + + case E_RAIL_ASCEND_XP: // ASCEND WEST + { + SetRotation(180); + SetPosY(floor(GetPosY()) + 0.2); + SpeedZ = 0; - case E_RAIL_ASCEND_XP: + if (SpeedX > 0) { - if (SpeedX > 0) + SpeedX = SpeedX - 0.4; + SpeedY = SpeedX; + } + else + { + if (SpeedX >= MAX_SPEED_NEGATIVE) { - SpeedX = SpeedX - 0.6; + SpeedX = SpeedX - 0.5; SpeedY = SpeedX; } else { - if (SpeedX >= -8) - { - SpeedX = SpeedX - 0.5; - SpeedY = SpeedX; - } - else - { - SpeedX = -8; - SpeedY = SpeedX; - } + SpeedX = MAX_SPEED_NEGATIVE; + SpeedY = SpeedX; } - break; } + break; + } + + case E_RAIL_CURVED_ZM_XM: // Ends pointing NORTH and WEST + { + SetRotation(315); // Set correct rotation server side + SetPosY(floor(GetPosY()) + 0.2); // Levitate dat cart + + if (SpeedZ > 0) // Cart moving south + { + SpeedX = (0 - SpeedZ); // Diagonally move southwest (which will make cart hit a southwest rail) + } + else if (SpeedX > 0) // Cart moving east + { + SpeedZ = (0 - SpeedX); // Diagonally move northeast + } + break; + } + + case E_RAIL_CURVED_ZM_XP: // Curved NORTH EAST + { + SetRotation(225); + SetPosY(floor(GetPosY()) + 0.2); + + if (SpeedZ > 0) + { + SpeedX = SpeedZ; + } + else if (SpeedX < 0) + { + SpeedZ = SpeedX; + } + break; + } + + case E_RAIL_CURVED_ZP_XM: // Curved SOUTH WEST + { + SetRotation(135); + SetPosY(floor(GetPosY()) + 0.2); + + if (SpeedZ < 0) + { + SpeedX = SpeedZ; + } + else if (SpeedX > 0) + { + SpeedZ = SpeedX; + } + break; + } - default: + case E_RAIL_CURVED_ZP_XP: // Curved SOUTH EAST + { + SetRotation(45); + SetPosY(floor(GetPosY()) + 0.2); + + if (SpeedZ < 0) + { + SpeedX = (0 - SpeedZ); + } + else if (SpeedX < 0) { - ASSERT(!"Unhandled rail meta!"); - break; + SpeedZ = (0 - SpeedX); } + break; + } + default: + { + ASSERT(!"Unhandled rail meta!"); // Dun dun DUN! + break; } } - + // Set speed to speed variables SetSpeedX(SpeedX); SetSpeedY(SpeedY); SetSpeedZ(SpeedZ); - // Pass to physics handlers in Entity.cpp and broadcast position to client - HandlePhysics(a_Dt, a_Chunk); + + // Broadcast position to client BroadcastMovementUpdate(); +} + + + + +void cMinecart::DoTakeDamage(TakeDamageInfo & TDI) +{ + super::DoTakeDamage(TDI); + + if (GetHealth() == 0) + { + Destroy(true); + } } diff --git a/source/Entities/Minecart.h b/source/Entities/Minecart.h index 91336673d..b3386fbc9 100644 --- a/source/Entities/Minecart.h +++ b/source/Entities/Minecart.h @@ -37,7 +37,10 @@ public: // cEntity overrides: virtual bool Initialize(cWorld * a_World) override; virtual void SpawnOn(cClientHandle & a_ClientHandle) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void HandlePhysics(float a_Dt, cChunk & a_Chunk) override; + void HandleRailPhysics(float a_Dt, cChunk & a_Chunk); + virtual void DoTakeDamage(TakeDamageInfo & TDI) override; + ePayload GetPayload(void) const { return m_Payload; } -- cgit v1.2.3 From 9c22cf15203ba524908d4c35c98f3f24e0e34837 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Tue, 3 Sep 2013 12:33:54 +0100 Subject: Fixed inconsistent meta naming --- source/Entities/Minecart.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source/Entities') diff --git a/source/Entities/Minecart.cpp b/source/Entities/Minecart.cpp index 685067e79..0c0b7b58a 100644 --- a/source/Entities/Minecart.cpp +++ b/source/Entities/Minecart.cpp @@ -99,7 +99,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) switch (BelowMeta) { - case E_RAIL_ZM_ZP: // NORTHSOUTH + case E_META_RAIL_ZM_ZP: // NORTHSOUTH { SetRotation(270); SpeedY = 0; // Don't move vertically as on ground @@ -124,7 +124,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_XM_XP: // EASTWEST + case E_META_RAIL_XM_XP: // EASTWEST { SetRotation(180); SpeedY = 0; @@ -146,7 +146,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_ASCEND_ZM: // ASCEND NORTH + case E_META_RAIL_ASCEND_ZM: // ASCEND NORTH { SetRotation(270); SetPosY(floor(GetPosY()) + 0.2); // It seems it doesn't work without levitation :/ @@ -175,7 +175,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_ASCEND_ZP: // ASCEND SOUTH + case E_META_RAIL_ASCEND_ZP: // ASCEND SOUTH { SetRotation(270); SetPosY(floor(GetPosY()) + 0.2); @@ -204,7 +204,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_ASCEND_XM: // ASCEND EAST + case E_META_RAIL_ASCEND_XM: // ASCEND EAST { SetRotation(180); SetPosY(floor(GetPosY()) + 0.2); @@ -231,7 +231,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_ASCEND_XP: // ASCEND WEST + case E_META_RAIL_ASCEND_XP: // ASCEND WEST { SetRotation(180); SetPosY(floor(GetPosY()) + 0.2); @@ -258,7 +258,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_CURVED_ZM_XM: // Ends pointing NORTH and WEST + case E_META_RAIL_CURVED_ZM_XM: // Ends pointing NORTH and WEST { SetRotation(315); // Set correct rotation server side SetPosY(floor(GetPosY()) + 0.2); // Levitate dat cart @@ -274,7 +274,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_CURVED_ZM_XP: // Curved NORTH EAST + case E_META_RAIL_CURVED_ZM_XP: // Curved NORTH EAST { SetRotation(225); SetPosY(floor(GetPosY()) + 0.2); @@ -290,7 +290,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_CURVED_ZP_XM: // Curved SOUTH WEST + case E_META_RAIL_CURVED_ZP_XM: // Curved SOUTH WEST { SetRotation(135); SetPosY(floor(GetPosY()) + 0.2); @@ -306,7 +306,7 @@ void cMinecart::HandleRailPhysics(float a_Dt, cChunk & a_Chunk) break; } - case E_RAIL_CURVED_ZP_XP: // Curved SOUTH EAST + case E_META_RAIL_CURVED_ZP_XP: // Curved SOUTH EAST { SetRotation(45); SetPosY(floor(GetPosY()) + 0.2); -- cgit v1.2.3