summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@hotmail.co.uk>2013-09-02 13:01:49 +0200
committerTiger Wang <ziwei.tiger@hotmail.co.uk>2013-09-02 13:01:49 +0200
commitb5c63d8fc50d9f8ff179988a9a14010de89f5d75 (patch)
treec01da79d1b1c514588f2bb2f724f57f9c182916e /source
parentPhysics enhancements (diff)
downloadcuberite-b5c63d8fc50d9f8ff179988a9a14010de89f5d75.tar
cuberite-b5c63d8fc50d9f8ff179988a9a14010de89f5d75.tar.gz
cuberite-b5c63d8fc50d9f8ff179988a9a14010de89f5d75.tar.bz2
cuberite-b5c63d8fc50d9f8ff179988a9a14010de89f5d75.tar.lz
cuberite-b5c63d8fc50d9f8ff179988a9a14010de89f5d75.tar.xz
cuberite-b5c63d8fc50d9f8ff179988a9a14010de89f5d75.tar.zst
cuberite-b5c63d8fc50d9f8ff179988a9a14010de89f5d75.zip
Diffstat (limited to 'source')
-rw-r--r--source/Entities/Minecart.cpp350
-rw-r--r--source/Entities/Minecart.h5
2 files changed, 242 insertions, 113 deletions
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; }