summaryrefslogtreecommitdiffstats
path: root/source/Entities/Minecart.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--source/Entities/Minecart.cpp323
1 files changed, 313 insertions, 10 deletions
diff --git a/source/Entities/Minecart.cpp b/source/Entities/Minecart.cpp
index 808579582..0c0b7b58a 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,9 @@ 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)
{
+ SetMass(20.f);
+ SetMaxHealth(6);
+ SetHealth(6);
}
@@ -24,30 +28,329 @@ cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) :
void cMinecart::SpawnOn(cClientHandle & a_ClientHandle)
{
- char Type = 0;
- switch (m_Payload) //Wiki.vg is outdated on this!!
+ char SubType = 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: 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, Type);
+ a_ClientHandle.SendSpawnVehicle(*this, 10, SubType); // 10 = Minecarts, SubType = What type of Minecart
}
-void cMinecart::Tick(float a_Dt, cChunk & a_Chunk)
+void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk)
{
- // TODO: the physics
+ 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.
+ */
+
+ // 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
+
+ switch (BelowMeta)
+ {
+ case E_META_RAIL_ZM_ZP: // NORTHSOUTH
+ {
+ 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
+ {
+ if (SpeedZ > 0)
+ {
+ // Going SOUTH, slow down
+ SpeedZ = SpeedZ - 0.1;
+ }
+ else
+ {
+ // Going NORTH, slow down
+ SpeedZ = SpeedZ + 0.1;
+ }
+ }
+ break;
+ }
+
+ case E_META_RAIL_XM_XP: // EASTWEST
+ {
+ SetRotation(180);
+ SpeedY = 0;
+ SpeedZ = 0;
+
+ SetPosY(floor(GetPosY()));
+
+ if (SpeedX != 0)
+ {
+ if (SpeedX > 0)
+ {
+ SpeedX = SpeedX - 0.1;
+ }
+ else
+ {
+ SpeedX = SpeedX + 0.1;
+ }
+ }
+ break;
+ }
+
+ case E_META_RAIL_ASCEND_ZM: // ASCEND NORTH
+ {
+ SetRotation(270);
+ SetPosY(floor(GetPosY()) + 0.2); // It seems it doesn't work without levitation :/
+ SpeedX = 0;
+
+ if (SpeedZ >= 0)
+ {
+ // SpeedZ POSITIVE, going SOUTH
+ if (SpeedZ <= MAX_SPEED) // Speed limit
+ {
+ SpeedZ = SpeedZ + 0.5; // Speed up
+ SpeedY = (0 - SpeedZ); // Downward movement is negative (0 minus positive numbers is negative)
+ }
+ else
+ {
+ SpeedZ = MAX_SPEED; // Enforce speed limit
+ SpeedY = (0 - SpeedZ);
+ }
+ }
+ 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_META_RAIL_ASCEND_ZP: // ASCEND SOUTH
+ {
+ SetRotation(270);
+ SetPosY(floor(GetPosY()) + 0.2);
+ SpeedX = 0;
+
+ if (SpeedZ > 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 NEGATIVE, going NORTH
+ SpeedZ = SpeedZ - 0.5; // Speed up
+ SpeedY = SpeedZ; // Downward movement negative
+ }
+ else
+ {
+ SpeedZ = MAX_SPEED_NEGATIVE; // Enforce speed limit
+ SpeedY = SpeedZ;
+ }
+ }
+ break;
+ }
+
+ case E_META_RAIL_ASCEND_XM: // ASCEND EAST
+ {
+ SetRotation(180);
+ SetPosY(floor(GetPosY()) + 0.2);
+ SpeedZ = 0;
+
+ if (SpeedX >= 0)
+ {
+ if (SpeedX <= MAX_SPEED)
+ {
+ SpeedX = SpeedX + 0.5;
+ SpeedY = (0 - SpeedX);
+ }
+ else
+ {
+ SpeedX = MAX_SPEED;
+ SpeedY = (0 - SpeedX);
+ }
+ }
+ else
+ {
+ SpeedX = SpeedX + 0.4;
+ SpeedY = (0 - SpeedX);
+ }
+ break;
+ }
+
+ case E_META_RAIL_ASCEND_XP: // ASCEND WEST
+ {
+ SetRotation(180);
+ SetPosY(floor(GetPosY()) + 0.2);
+ SpeedZ = 0;
+
+ if (SpeedX > 0)
+ {
+ SpeedX = SpeedX - 0.4;
+ SpeedY = SpeedX;
+ }
+ else
+ {
+ if (SpeedX >= MAX_SPEED_NEGATIVE)
+ {
+ SpeedX = SpeedX - 0.5;
+ SpeedY = SpeedX;
+ }
+ else
+ {
+ SpeedX = MAX_SPEED_NEGATIVE;
+ SpeedY = SpeedX;
+ }
+ }
+ break;
+ }
+
+ 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
+
+ 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_META_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_META_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;
+ }
+
+ case E_META_RAIL_CURVED_ZP_XP: // Curved SOUTH EAST
+ {
+ SetRotation(45);
+ SetPosY(floor(GetPosY()) + 0.2);
+
+ if (SpeedZ < 0)
+ {
+ SpeedX = (0 - SpeedZ);
+ }
+ else if (SpeedX < 0)
+ {
+ SpeedZ = (0 - SpeedX);
+ }
+ break;
+ }
+
+ default:
+ {
+ ASSERT(!"Unhandled rail meta!"); // Dun dun DUN!
+ break;
+ }
+ }
+
+ // Set speed to speed variables
+ SetSpeedX(SpeedX);
+ SetSpeedY(SpeedY);
+ SetSpeedZ(SpeedZ);
+
+
+ // Broadcast position to client
+ BroadcastMovementUpdate();
+}
+
+
+
+
+
+void cMinecart::DoTakeDamage(TakeDamageInfo & TDI)
+{
+ super::DoTakeDamage(TDI);
+
+ if (GetHealth() == 0)
+ {
+ Destroy(true);
+ }
}