From b3d4e0fca665502b727f0088a3a20aac1b9ad073 Mon Sep 17 00:00:00 2001 From: LogicParrot Date: Tue, 3 May 2016 10:48:39 +0300 Subject: Fixed death on teleportation or leaving Minecart (#3181) --- src/Entities/Entity.h | 2 +- src/Entities/Pawn.cpp | 18 ++++++++++++++++++ src/Entities/Pawn.h | 4 ++++ src/Entities/Player.cpp | 14 +++++++++----- 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h index b00201f3a..db9be63ad 100644 --- a/src/Entities/Entity.h +++ b/src/Entities/Entity.h @@ -215,7 +215,7 @@ public: void SetPosY (double a_PosY) { SetPosition({m_Position.x, a_PosY, m_Position.z}); } void SetPosZ (double a_PosZ) { SetPosition({m_Position.x, m_Position.y, a_PosZ}); } void SetPosition(double a_PosX, double a_PosY, double a_PosZ) { SetPosition({a_PosX, a_PosY, a_PosZ}); } - void SetPosition(const Vector3d & a_Position); + virtual void SetPosition(const Vector3d & a_Position); void SetYaw (double a_Yaw); // In degrees, normalizes to [-180, +180) void SetPitch (double a_Pitch); // In degrees, normalizes to [-180, +180) void SetRoll (double a_Roll); // In degrees, normalizes to [-180, +180) diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp index 3dea74851..69c2db5e7 100644 --- a/src/Entities/Pawn.cpp +++ b/src/Entities/Pawn.cpp @@ -250,6 +250,24 @@ void cPawn::TargetingMe(cMonster * a_Monster) +void cPawn::SetPosition(double a_PosX, double a_PosY, double a_PosZ) +{ + SetPosition({a_PosX, a_PosY, a_PosZ}); +} + + + + + +void cPawn::SetPosition(const Vector3d & a_Position) +{ + super::SetPosition(a_Position); + m_LastGroundHeight = a_Position.y; // Prevent fall damage on teleport +} + + + + void cPawn::HandleFalling(void) { diff --git a/src/Entities/Pawn.h b/src/Entities/Pawn.h index 05bc09e88..d6f7e052a 100644 --- a/src/Entities/Pawn.h +++ b/src/Entities/Pawn.h @@ -69,6 +69,10 @@ public: /** Add the monster to the list of monsters targeting this pawn. (Does not check if already in list!) */ void TargetingMe(cMonster * a_Monster); + void SetPosition(double a_PosX, double a_PosY, double a_PosZ); + + virtual void SetPosition(const Vector3d & a_Position) override; + protected: typedef std::map tEffectMap; tEffectMap m_EntityEffects; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index d131699d3..a5868b528 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -2468,17 +2468,21 @@ void cPlayer::Detach() int PosZ = POSZ_TOINT; // Search for a position within an area to teleport player after detachment - // Position must be solid land, and occupied by a nonsolid block + // Position must be solid land with two air blocks above. // If nothing found, player remains where they are - for (int x = PosX - 2; x <= (PosX + 2); ++x) + for (int x = PosX - 1; x <= (PosX + 1); ++x) { for (int y = PosY; y <= (PosY + 3); ++y) { - for (int z = PosZ - 2; z <= (PosZ + 2); ++z) + for (int z = PosZ - 1; z <= (PosZ + 1); ++z) { - if (!cBlockInfo::IsSolid(m_World->GetBlock(x, y, z)) && cBlockInfo::IsSolid(m_World->GetBlock(x, y - 1, z))) + if ( + (m_World->GetBlock(x, y, z) == E_BLOCK_AIR) && + (m_World->GetBlock(x, y + 1, z) == E_BLOCK_AIR) && + cBlockInfo::IsSolid(m_World->GetBlock(x, y - 1, z)) + ) { - TeleportToCoords(x, y, z); + TeleportToCoords(x + 0.5, y, z + 0.5); return; } } -- cgit v1.2.3