From ddd03a050bfaaffef9abd573fe6c8e1af3948048 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 18 Jan 2014 20:58:26 +0000 Subject: Minecart collision and general improvements + Implemented collision on one type of rail * Improved curved rails somewhat * Fixed a crash bug --- src/Entities/Minecart.cpp | 305 +++++++++++++++++++++++++++++++++++----------- src/Entities/Minecart.h | 7 +- 2 files changed, 242 insertions(+), 70 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 7f3fea5ec..ad63f848e 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -19,6 +19,70 @@ +class cMinecartCollisionCallback : + public cEntityCallback +{ +public: + cMinecartCollisionCallback(Vector3d a_Pos, double a_Height, double a_Width, int a_UniqueID, int a_AttacheeUniqueID) : + m_Pos(a_Pos), + m_Height(a_Height), + m_Width(a_Width), + m_DoesInteserct(false), + m_CollidedEntityPos(0, 0, 0), + m_UniqueID(a_UniqueID), + m_AttacheeUniqueID(a_AttacheeUniqueID) + { + } + + virtual bool Item(cEntity * a_Entity) override + { + ASSERT(a_Entity != NULL); + + if (!a_Entity->IsPlayer() && !a_Entity->IsMob() && !a_Entity->IsMinecart() && !a_Entity->IsBoat()) + { + return false; + } + else if ((a_Entity->GetUniqueID() == m_UniqueID) || (a_Entity->GetUniqueID() == m_AttacheeUniqueID)) + { + return false; + } + + cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); + cBoundingBox bbMinecart(Vector3d(m_Pos.x, floor(m_Pos.y), m_Pos.z), m_Width / 2, m_Height); + + if (bbEntity.DoesIntersect(bbMinecart)) + { + m_CollidedEntityPos = a_Entity->GetPosition(); + m_DoesInteserct = true; + return true; + } + return false; + } + + bool FoundIntersection(void) const + { + return m_DoesInteserct; + } + + Vector3d GetCollidedEntityPosition(void) const + { + return m_CollidedEntityPos; + } + +protected: + bool m_DoesInteserct; + + Vector3d m_CollidedEntityPos; + + Vector3d m_Pos; + double m_Height, m_Width; + int m_UniqueID; + int m_AttacheeUniqueID; +}; + + + + 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), @@ -30,7 +94,7 @@ cMinecart::cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z) : SetMass(20.f); SetMaxHealth(6); SetHealth(6); - SetWidth(1.2); + SetWidth(1); SetHeight(0.9); } @@ -153,7 +217,9 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) SetSpeedY(0); // Don't move vertically as on ground SetSpeedX(0); // Correct diagonal movement from curved rails - if (TestBlockCollision(a_RailMeta)) return; + // Execute both the entity and block collision checks + bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); + if (EntCol || BlckCol) return; if (GetSpeedZ() != 0) // Don't do anything if cart is stationary { @@ -177,7 +243,8 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) SetSpeedY(0); SetSpeedZ(0); - if (TestBlockCollision(a_RailMeta)) return; + bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); + if (EntCol || BlckCol) return; if (GetSpeedX() != 0) { @@ -281,24 +348,11 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) SetRotation(315); // Set correct rotation server side SetPosY(floor(GetPosY()) + 0.55); // Levitate dat cart - if (TestBlockCollision(a_RailMeta)) return; + TestBlockCollision(a_RailMeta); + TestEntityCollision(a_RailMeta); + + // SnapToRail handles turning - if (GetSpeedZ() > 0) // Cart moving south - { - int OldX = (int)floor(GetPosX()); - AddSpeedX(-GetSpeedZ() + 0.5); // See below - AddPosX(-GetSpeedZ() * (a_Dt / 1000)); // Diagonally move southwest (which will make cart hit a southwest rail) - // If we are already at southwest rail, set Z speed to zero as we can be moving so fast, MCS doesn't tick fast enough to active the handle for the rail... - // ...and so we derail unexpectedly. - if (GetPosX() <= OldX - 1) SetSpeedZ(0); - } - else if (GetSpeedX() > 0) // Cart moving east - { - int OldZ = (int)floor(GetPosZ()); - AddSpeedZ(-GetSpeedX() + 0.5); - AddPosZ(-GetSpeedX() * (a_Dt / 1000)); // Diagonally move northeast - if (GetPosZ() <= OldZ - 1) SetSpeedX(0); - } break; } case E_META_RAIL_CURVED_ZM_XP: // Curved NORTH EAST @@ -306,22 +360,9 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) SetRotation(225); SetPosY(floor(GetPosY()) + 0.55); - if (TestBlockCollision(a_RailMeta)) return; + TestBlockCollision(a_RailMeta); + TestEntityCollision(a_RailMeta); - if (GetSpeedZ() > 0) - { - int OldX = (int)floor(GetPosX()); - AddSpeedX(GetSpeedZ() - 0.5); - AddPosX(GetSpeedZ() * (a_Dt / 1000)); - if (GetPosX() >= OldX + 1) SetSpeedZ(0); - } - else if (GetSpeedX() < 0) - { - int OldZ = (int)floor(GetPosZ()); - AddSpeedZ(GetSpeedX() + 0.5); - AddPosZ(GetSpeedX() * (a_Dt / 1000)); - if (GetPosZ() <= OldZ - 1) SetSpeedX(0); - } break; } case E_META_RAIL_CURVED_ZP_XM: // Curved SOUTH WEST @@ -329,22 +370,9 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) SetRotation(135); SetPosY(floor(GetPosY()) + 0.55); - if (TestBlockCollision(a_RailMeta)) return; + TestBlockCollision(a_RailMeta); + TestEntityCollision(a_RailMeta); - if (GetSpeedZ() < 0) - { - int OldX = (int)floor(GetPosX()); - AddSpeedX(GetSpeedZ() + 0.5); - AddPosX(GetSpeedZ() * (a_Dt / 1000)); - if (GetPosX() <= OldX - 1) SetSpeedZ(0); - } - else if (GetSpeedX() > 0) - { - int OldZ = (int)floor(GetPosZ()); - AddSpeedZ(GetSpeedX() - 0.5); - AddPosZ(GetSpeedX() * (a_Dt / 1000)); - if (GetPosZ() >= OldZ + 1) SetSpeedX(0); - } break; } case E_META_RAIL_CURVED_ZP_XP: // Curved SOUTH EAST @@ -352,22 +380,9 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) SetRotation(45); SetPosY(floor(GetPosY()) + 0.55); - if (TestBlockCollision(a_RailMeta)) return; + TestBlockCollision(a_RailMeta); + TestEntityCollision(a_RailMeta); - if (GetSpeedZ() < 0) - { - int OldX = (int)floor(GetPosX()); - AddSpeedX(-GetSpeedZ() - 0.5); - AddPosX(-GetSpeedZ() * (a_Dt / 1000)); - if (GetPosX() >= OldX + 1) SetSpeedZ(0); - } - else if (GetSpeedX() < 0) - { - int OldZ = (int)floor(GetPosZ()); - AddSpeedZ(-GetSpeedX() - 0.5); - AddPosZ(-GetSpeedX() * (a_Dt / 1000)); - if (GetPosZ() >= OldZ + 1) SetSpeedX(0); - } break; } default: @@ -481,6 +496,102 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetPosX(floor(GetPosX()) + 0.5); break; } + case E_META_RAIL_CURVED_ZM_XM: + { + if (GetPosZ() < floor(GetPosZ()) + 0.5) + { + if (GetSpeedX() > 0) + { + SetSpeedZ(-GetSpeedX() * 0.7); + } + + SetSpeedX(0); + SetPosX(floor(GetPosX()) + 0.5); + } + else + { + if (GetSpeedZ() > 0) + { + SetSpeedX(-GetSpeedZ() * 0.7); + } + + SetSpeedZ(0); + SetPosZ(floor(GetPosZ()) + 0.5); + } + break; + } + case E_META_RAIL_CURVED_ZM_XP: + { + if (GetPosZ() < floor(GetPosZ()) + 0.5) + { + if (GetSpeedX() < 0) + { + SetSpeedZ(GetSpeedX() * 0.7); + } + + SetSpeedX(0); + SetPosX(floor(GetPosX()) + 0.5); + } + else + { + if (GetSpeedZ() > 0) + { + SetSpeedX(GetSpeedZ() * 0.7); + } + + SetSpeedZ(0); + SetPosZ(floor(GetPosZ()) + 0.5); + } + break; + } + case E_META_RAIL_CURVED_ZP_XM: + { + if (GetPosZ() < floor(GetPosZ()) + 0.5) + { + if (GetSpeedZ() < 0) + { + SetSpeedX(GetSpeedZ() * 0.7); + } + + SetSpeedZ(0); + SetPosZ(floor(GetPosZ()) + 0.5); + } + else + { + if (GetSpeedX() > 0) + { + SetSpeedZ(GetSpeedX() * 0.7); + } + + SetSpeedX(0); + SetPosX(floor(GetPosX()) + 0.5); + } + break; + } + case E_META_RAIL_CURVED_ZP_XP: + { + if (GetPosZ() < floor(GetPosZ()) + 0.5) + { + if (GetSpeedZ() < 0) + { + SetSpeedX(-GetSpeedZ() * 0.7); + } + + SetSpeedZ(0); + SetPosZ(floor(GetPosZ()) + 0.5); + } + else + { + if (GetSpeedX() < 0) + { + SetSpeedZ(-GetSpeedX() * 0.7); + } + + SetSpeedX(0); + SetPosX(floor(GetPosX()) + 0.5); + } + break; + } default: break; } } @@ -512,7 +623,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) } } } - else + else if (GetSpeedZ() < 0) { BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ()) - 1); if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) @@ -548,7 +659,7 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) } } } - else + else if (GetSpeedX() < 0) { BLOCKTYPE Block = m_World->GetBlock((int)floor(GetPosX()) - 1, (int)floor(GetPosY()), (int)floor(GetPosZ())); if (!IsBlockRail(Block) && g_BlockIsSolid[Block]) @@ -596,10 +707,68 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) +bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) +{ + switch (a_RailMeta) + { + case E_META_RAIL_ZM_ZP: + { + cMinecartCollisionCallback MinecartCollisionCallback(GetPosition(), GetHeight(), GetWidth(), GetUniqueID(), ((m_Attachee == NULL) ? -1 : m_Attachee->GetUniqueID())); + m_World->ForEachEntity(MinecartCollisionCallback); + + if (MinecartCollisionCallback.FoundIntersection()) + { + if (MinecartCollisionCallback.GetCollidedEntityPosition().z >= GetPosZ()) + { + if (((-GetSpeedZ()) * 0.4) < 0.01) + { + AddSpeedZ(-4); + } + else + { + SetSpeedZ((-GetSpeedZ()) * 0.4); + } + } + else + { + if ((GetSpeedZ() * 0.4) < 0.01) + { + AddSpeedZ(4); + } + else + { + SetSpeedZ(GetSpeedZ() * 0.4); + } + } + return true; + } + break; + } + case E_META_RAIL_XM_XP: + { + + break; + } + case E_META_RAIL_CURVED_ZM_XM: + case E_META_RAIL_CURVED_ZM_XP: + case E_META_RAIL_CURVED_ZP_XM: + case E_META_RAIL_CURVED_ZP_XP: + { + + break; + } + default: break; + } + return false; +} + + + + void cMinecart::DoTakeDamage(TakeDamageInfo & TDI) { - if (TDI.Attacker->IsPlayer() && ((cPlayer *)TDI.Attacker)->IsGameModeCreative()) + if ((TDI.Attacker != NULL) && TDI.Attacker->IsPlayer() && ((cPlayer *)TDI.Attacker)->IsGameModeCreative()) { Destroy(); TDI.FinalDamage = GetMaxHealth(); // Instant hit for creative diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index 1ebddfdda..1c3ea3220 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -79,10 +79,13 @@ protected: */ void HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt); - /** Snaps a minecart to a rail's axis, resetting its speed */ + /** Snaps a mincecart to a rail's axis, resetting its speed + For curved rails, it changes the cart's direction as well as snapping it to axis */ void SnapToRail(NIBBLETYPE a_RailMeta); - /** Tests is a solid block is in front of a cart, and stops the cart (and returns true) if so; returns false if no obstruction*/ + /** Tests if a solid block is in front of a cart, and stops the cart (and returns true) if so; returns false if no obstruction */ bool TestBlockCollision(NIBBLETYPE a_RailMeta); + /** Tests if this mincecart's bounding box is intersecting another entity's bounding box (collision) and pushes mincecart away */ + bool TestEntityCollision(NIBBLETYPE a_RailMeta); } ; -- cgit v1.2.3 From 8467f5dfaea596a0b7e294cf1b7dce224c41d7b9 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Jan 2014 14:52:45 +0000 Subject: Added more rail functionality --- src/Entities/Minecart.h | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index a4ecb33ad..87f785538 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -15,20 +15,6 @@ -inline bool IsBlockRail(BLOCKTYPE a_BlockType) - { - return ( - (a_BlockType == E_BLOCK_RAIL) || - (a_BlockType == E_BLOCK_ACTIVATOR_RAIL) || - (a_BlockType == E_BLOCK_DETECTOR_RAIL) || - (a_BlockType == E_BLOCK_POWERED_RAIL) - ) ; - } - - - - - class cMinecart : public cEntity { -- cgit v1.2.3 From 9a580146e43cc5cf6c84455b75976020467da32f Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Jan 2014 18:27:06 +0000 Subject: Minecart improvements and fixes * Fixed curved rails * Fixed detector rails in certain situations * Fixed powered rails and others passing bad meta to SnapToRail() --- src/Entities/Minecart.cpp | 76 +++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 33 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index c8f43a3e6..643eefb39 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -160,10 +160,17 @@ void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk) if (IsBlockRail(InsideType)) AddPosY(1); // Push cart upwards } + bool WasDetectorRail = false; if (IsBlockRail(InsideType)) { - bool WasDetectorRail = false; - SnapToRail(InsideMeta); + if (InsideType == E_BLOCK_RAIL) + { + SnapToRail(InsideMeta); + } + else + { + SnapToRail(InsideMeta & 0x07); + } switch (InsideType) { @@ -180,12 +187,6 @@ void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk) } AddPosition(GetSpeed() * (a_Dt / 1000)); // Commit changes; as we use our own engine when on rails, this needs to be done, whereas it is normally in Entity.cpp - - if (m_bIsOnDetectorRail && !WasDetectorRail) - { - m_World->SetBlock(m_DetectorRailPosition.x, m_DetectorRailPosition.y, m_DetectorRailPosition.z, E_BLOCK_DETECTOR_RAIL, m_World->GetBlockMeta(m_DetectorRailPosition) & 0x07); - m_bIsOnDetectorRail = false; - } } else { @@ -193,6 +194,17 @@ void cMinecart::HandlePhysics(float a_Dt, cChunk & a_Chunk) SetPosY(floor(GetPosY()) + 0.35); // HandlePhysics overrides this if minecart can fall, else, it is to stop ground clipping minecart bottom when off-rail super::HandlePhysics(a_Dt, *Chunk); } + + if (m_bIsOnDetectorRail && !Vector3i((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ())).Equals(m_DetectorRailPosition)) + { + m_World->SetBlock(m_DetectorRailPosition.x, m_DetectorRailPosition.y, m_DetectorRailPosition.z, E_BLOCK_DETECTOR_RAIL, m_World->GetBlockMeta(m_DetectorRailPosition) & 0x07); + m_bIsOnDetectorRail = false; + } + else if (WasDetectorRail) + { + m_bIsOnDetectorRail = true; + m_DetectorRailPosition = Vector3i((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ())); + } // Broadcast positioning changes to client BroadcastMovementUpdate(); @@ -425,11 +437,11 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) { if (GetSpeedZ() > 0) { - AddSpeedZ(AccelDecelNegSpeed); + AddSpeedZ(AccelDecelSpeed); } else { - AddSpeedZ(AccelDecelSpeed); + AddSpeedZ(AccelDecelNegSpeed); } } break; @@ -465,9 +477,6 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) void cMinecart::HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) { - m_bIsOnDetectorRail = true; - m_DetectorRailPosition = Vector3i((int)floor(GetPosX()), (int)floor(GetPosY()), (int)floor(GetPosZ())); - m_World->SetBlockMeta(m_DetectorRailPosition, a_RailMeta | 0x08); HandleRailPhysics(a_RailMeta & 0x07, a_Dt); @@ -497,9 +506,20 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetPosX(floor(GetPosX()) + 0.5); break; } + // Curved rail physics: once minecart has reached more than half of the block in the direction that it is travelling in, jerk it in the direction of curvature case E_META_RAIL_CURVED_ZM_XM: { - if (GetPosZ() < floor(GetPosZ()) + 0.5) + if (GetPosZ() > floor(GetPosZ()) + 0.5) + { + if (GetSpeedZ() > 0) + { + SetSpeedX(-GetSpeedZ() * 0.7); + } + + SetSpeedZ(0); + SetPosZ(floor(GetPosZ()) + 0.5); + } + else if (GetPosX() > floor(GetPosX()) + 0.5) { if (GetSpeedX() > 0) { @@ -509,21 +529,21 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedX(0); SetPosX(floor(GetPosX()) + 0.5); } - else + break; + } + case E_META_RAIL_CURVED_ZM_XP: + { + if (GetPosZ() > floor(GetPosZ()) + 0.5) { if (GetSpeedZ() > 0) { - SetSpeedX(-GetSpeedZ() * 0.7); + SetSpeedX(GetSpeedZ() * 0.7); } SetSpeedZ(0); SetPosZ(floor(GetPosZ()) + 0.5); } - break; - } - case E_META_RAIL_CURVED_ZM_XP: - { - if (GetPosZ() < floor(GetPosZ()) + 0.5) + else if (GetPosX() < floor(GetPosX()) + 0.5) { if (GetSpeedX() < 0) { @@ -533,16 +553,6 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedX(0); SetPosX(floor(GetPosX()) + 0.5); } - else - { - if (GetSpeedZ() > 0) - { - SetSpeedX(GetSpeedZ() * 0.7); - } - - SetSpeedZ(0); - SetPosZ(floor(GetPosZ()) + 0.5); - } break; } case E_META_RAIL_CURVED_ZP_XM: @@ -557,7 +567,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedZ(0); SetPosZ(floor(GetPosZ()) + 0.5); } - else + else if (GetPosX() > floor(GetPosX()) + 0.5) { if (GetSpeedX() > 0) { @@ -581,7 +591,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedZ(0); SetPosZ(floor(GetPosZ()) + 0.5); } - else + else if (GetPosX() < floor(GetPosX()) + 0.5) { if (GetSpeedX() < 0) { -- cgit v1.2.3 From 3700ad8546dfa7649bb172610dfef4b365eb2a7b Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Jan 2014 18:42:05 +0000 Subject: Added one more direction into collision checks * Added direction XM_XP * Improved performance, thanks STR and xoft --- src/Entities/Minecart.cpp | 77 +++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 26 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 643eefb39..df1e48a60 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -720,56 +720,81 @@ bool cMinecart::TestBlockCollision(NIBBLETYPE a_RailMeta) bool cMinecart::TestEntityCollision(NIBBLETYPE a_RailMeta) { + cMinecartCollisionCallback MinecartCollisionCallback(GetPosition(), GetHeight(), GetWidth(), GetUniqueID(), ((m_Attachee == NULL) ? -1 : m_Attachee->GetUniqueID())); + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk((int)floor(GetPosX()), (int)floor(GetPosZ()), ChunkX, ChunkZ); + m_World->ForEachEntityInChunk(ChunkX, ChunkZ, MinecartCollisionCallback); + + if (!MinecartCollisionCallback.FoundIntersection()) + { + return false; + } + switch (a_RailMeta) { case E_META_RAIL_ZM_ZP: { - cMinecartCollisionCallback MinecartCollisionCallback(GetPosition(), GetHeight(), GetWidth(), GetUniqueID(), ((m_Attachee == NULL) ? -1 : m_Attachee->GetUniqueID())); - m_World->ForEachEntity(MinecartCollisionCallback); - - if (MinecartCollisionCallback.FoundIntersection()) + if (MinecartCollisionCallback.GetCollidedEntityPosition().z >= GetPosZ()) { - if (MinecartCollisionCallback.GetCollidedEntityPosition().z >= GetPosZ()) + if ((-GetSpeedZ() * 0.4) < 0.01) { - if (((-GetSpeedZ()) * 0.4) < 0.01) - { - AddSpeedZ(-4); - } - else - { - SetSpeedZ((-GetSpeedZ()) * 0.4); - } + AddSpeedZ(-4); } else { - if ((GetSpeedZ() * 0.4) < 0.01) - { - AddSpeedZ(4); - } - else - { - SetSpeedZ(GetSpeedZ() * 0.4); - } + SetSpeedZ(-GetSpeedZ() * 0.4); } - return true; } - break; + else + { + if ((GetSpeedZ() * 0.4) < 0.01) + { + AddSpeedZ(4); + } + else + { + SetSpeedZ(GetSpeedZ() * 0.4); + } + } + return true; } case E_META_RAIL_XM_XP: { - - break; + if (MinecartCollisionCallback.GetCollidedEntityPosition().x >= GetPosX()) + { + if ((-GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX(-4); + } + else + { + SetSpeedX(-GetSpeedX() * 0.4); + } + } + else + { + if ((GetSpeedX() * 0.4) < 0.01) + { + AddSpeedX(4); + } + else + { + SetSpeedX(GetSpeedX() * 0.4); + } + } + return true; } case E_META_RAIL_CURVED_ZM_XM: case E_META_RAIL_CURVED_ZM_XP: case E_META_RAIL_CURVED_ZP_XM: case E_META_RAIL_CURVED_ZP_XP: { - + // TODO - simply can't be bothered right now break; } default: break; } + return false; } -- cgit v1.2.3 From 83cbe8c13996747a49e940f77282ef68de87eba0 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Jan 2014 19:31:17 +0000 Subject: Begin implementing ascending rails --- src/Entities/Minecart.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++-- src/Entities/Minecart.h | 3 +++ 2 files changed, 45 insertions(+), 2 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index df1e48a60..6477fb1ca 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -360,6 +360,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) { SetYaw(315); // Set correct rotation server side SetPosY(floor(GetPosY()) + 0.55); // Levitate dat cart + SetSpeedY(0); TestBlockCollision(a_RailMeta); TestEntityCollision(a_RailMeta); @@ -372,6 +373,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) { SetYaw(225); SetPosY(floor(GetPosY()) + 0.55); + SetSpeedY(0); TestBlockCollision(a_RailMeta); TestEntityCollision(a_RailMeta); @@ -382,6 +384,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) { SetYaw(135); SetPosY(floor(GetPosY()) + 0.55); + SetSpeedY(0); TestBlockCollision(a_RailMeta); TestEntityCollision(a_RailMeta); @@ -392,6 +395,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) { SetYaw(45); SetPosY(floor(GetPosY()) + 0.55); + SetSpeedY(0); TestBlockCollision(a_RailMeta); TestEntityCollision(a_RailMeta); @@ -431,7 +435,8 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) SetSpeedY(0); SetSpeedX(0); - if (TestBlockCollision(a_RailMeta)) return; + bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); + if (EntCol || BlckCol) return; if (GetSpeedZ() != 0) { @@ -453,7 +458,8 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) SetSpeedY(0); SetSpeedZ(0); - if (TestBlockCollision(a_RailMeta)) return; + bool BlckCol = TestBlockCollision(a_RailMeta), EntCol = TestEntityCollision(a_RailMeta); + if (EntCol || BlckCol) return; if (GetSpeedX() != 0) { @@ -468,6 +474,27 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) } break; } + case E_META_RAIL_ASCEND_XM: + { + SetYaw(180); + SetSpeedZ(0); + + if (GetSpeedX() >= 0) + { + if (GetSpeedX() <= MAX_SPEED) + { + AddSpeedX(1); + SetSpeedY(-GetSpeedX()); + } + } + else + { + AddSpeedX(-1); + SetSpeedY(-GetSpeedX()); + } + break; + } + default: ASSERT(!"Unhandled powered rail metadata!"); break; } } @@ -479,6 +506,15 @@ void cMinecart::HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) { m_World->SetBlockMeta(m_DetectorRailPosition, a_RailMeta | 0x08); + // No special handling + HandleRailPhysics(a_RailMeta & 0x07, a_Dt); +} + + + + +void cMinecart::HandleActivatorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) +{ HandleRailPhysics(a_RailMeta & 0x07, a_Dt); } @@ -529,6 +565,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedX(0); SetPosX(floor(GetPosX()) + 0.5); } + SetSpeedY(0); break; } case E_META_RAIL_CURVED_ZM_XP: @@ -553,6 +590,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedX(0); SetPosX(floor(GetPosX()) + 0.5); } + SetSpeedY(0); break; } case E_META_RAIL_CURVED_ZP_XM: @@ -577,6 +615,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedX(0); SetPosX(floor(GetPosX()) + 0.5); } + SetSpeedY(0); break; } case E_META_RAIL_CURVED_ZP_XP: @@ -601,6 +640,7 @@ void cMinecart::SnapToRail(NIBBLETYPE a_RailMeta) SetSpeedX(0); SetPosX(floor(GetPosX()) + 0.5); } + SetSpeedY(0); break; } default: break; diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index 87f785538..073e78953 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -65,6 +65,9 @@ protected: */ void HandleDetectorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt); + /** Handles activator rails - placeholder for future implementation */ + void HandleActivatorRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt); + /** Snaps a mincecart to a rail's axis, resetting its speed For curved rails, it changes the cart's direction as well as snapping it to axis */ void SnapToRail(NIBBLETYPE a_RailMeta); -- cgit v1.2.3 From f39daabf7eb4f54bda0f6385aff75dd4f22f75ca Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 24 Jan 2014 19:39:39 +0000 Subject: Added more minecart powered rail directions --- src/Entities/Minecart.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 6477fb1ca..78ec017cd 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -474,7 +474,7 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) } break; } - case E_META_RAIL_ASCEND_XM: + case E_META_RAIL_ASCEND_XM: // ASCEND EAST { SetYaw(180); SetSpeedZ(0); @@ -483,16 +483,76 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) { if (GetSpeedX() <= MAX_SPEED) { - AddSpeedX(1); + AddSpeedX(AccelDecelSpeed); SetSpeedY(-GetSpeedX()); } } else { - AddSpeedX(-1); + AddSpeedX(AccelDecelNegSpeed); SetSpeedY(-GetSpeedX()); } break; + } + case E_META_RAIL_ASCEND_XP: // ASCEND WEST + { + SetYaw(180); + SetSpeedZ(0); + + if (GetSpeedX() > 0) + { + AddSpeedX(AccelDecelSpeed); + SetSpeedY(GetSpeedX()); + } + else + { + if (GetSpeedX() >= MAX_SPEED_NEGATIVE) + { + AddSpeedX(AccelDecelNegSpeed); + SetSpeedY(GetSpeedX()); + } + } + break; + } + case E_META_RAIL_ASCEND_ZM: // ASCEND NORTH + { + SetYaw(270); + SetSpeedX(0); + + if (GetSpeedZ() >= 0) + { + if (GetSpeedZ() <= MAX_SPEED) + { + AddSpeedZ(AccelDecelSpeed); + SetSpeedY(-GetSpeedZ()); + } + } + else + { + AddSpeedZ(AccelDecelNegSpeed); + SetSpeedY(-GetSpeedZ()); + } + break; + } + case E_META_RAIL_ASCEND_ZP: // ASCEND SOUTH + { + SetYaw(270); + SetSpeedX(0); + + if (GetSpeedZ() > 0) + { + AddSpeedZ(AccelDecelSpeed); + SetSpeedY(GetSpeedZ()); + } + else + { + if (GetSpeedZ() >= MAX_SPEED_NEGATIVE) + { + AddSpeedZ(AccelDecelNegSpeed); + SetSpeedY(GetSpeedZ()); + } + } + break; } default: ASSERT(!"Unhandled powered rail metadata!"); break; } -- cgit v1.2.3 From 398e159f5f3c913079b0f89c6bf4f5fa41466307 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sat, 25 Jan 2014 20:33:23 +0000 Subject: Rail speed tweak --- src/Entities/Minecart.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/Entities') diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 78ec017cd..a650927b1 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -416,8 +416,8 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, float a_Dt) void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) { // Initialise to 'slow down' values - int AccelDecelSpeed = -1; - int AccelDecelNegSpeed = 1; + int AccelDecelSpeed = -2; + int AccelDecelNegSpeed = 2; if ((a_RailMeta & 0x8) == 0x8) { -- cgit v1.2.3