diff options
author | madmaxoft <github@xoft.cz> | 2013-09-05 17:44:22 +0200 |
---|---|---|
committer | madmaxoft <github@xoft.cz> | 2013-09-05 17:44:22 +0200 |
commit | cdaa48377846c688b4c003c35e02529ba00c779c (patch) | |
tree | dfb4d74621fc06768d4712dba4a297e6cc0e1b78 /source/Entities | |
parent | Removed TimedWait from cEvent. (diff) | |
parent | Fixed inconsistent meta naming (diff) | |
download | cuberite-cdaa48377846c688b4c003c35e02529ba00c779c.tar cuberite-cdaa48377846c688b4c003c35e02529ba00c779c.tar.gz cuberite-cdaa48377846c688b4c003c35e02529ba00c779c.tar.bz2 cuberite-cdaa48377846c688b4c003c35e02529ba00c779c.tar.lz cuberite-cdaa48377846c688b4c003c35e02529ba00c779c.tar.xz cuberite-cdaa48377846c688b4c003c35e02529ba00c779c.tar.zst cuberite-cdaa48377846c688b4c003c35e02529ba00c779c.zip |
Diffstat (limited to '')
-rw-r--r-- | source/Entities/Entity.cpp | 29 | ||||
-rw-r--r-- | source/Entities/Entity.h | 2 | ||||
-rw-r--r-- | source/Entities/Minecart.cpp | 323 | ||||
-rw-r--r-- | source/Entities/Minecart.h | 5 |
4 files changed, 337 insertions, 22 deletions
diff --git a/source/Entities/Entity.cpp b/source/Entities/Entity.cpp index b936d8d73..56fd36a05 100644 --- a/source/Entities/Entity.cpp +++ b/source/Entities/Entity.cpp @@ -503,6 +503,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 @@ -545,18 +546,26 @@ 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) + // Friction + if (NextSpeed.SqrLength() > 0.0004f) { - NextSpeed.x = 0; - } - NextSpeed.z *= 0.7f / (1 + a_Dt); - if (fabs(NextSpeed.z) < 0.05) - { - NextSpeed.z = 0; + 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/Entity.h b/source/Entities/Entity.h index f407cd2c1..2d058abae 100644 --- a/source/Entities/Entity.h +++ b/source/Entities/Entity.h @@ -351,7 +351,7 @@ protected: bool m_bOnGround; float m_Gravity; - + // Last Position. double m_LastPosX, m_LastPosY, m_LastPosZ; 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); + } } diff --git a/source/Entities/Minecart.h b/source/Entities/Minecart.h index c1a0e84a0..f98b02bb5 100644 --- a/source/Entities/Minecart.h +++ b/source/Entities/Minecart.h @@ -36,7 +36,10 @@ public: // cEntity overrides: 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; } |