summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorworktycho <work.tycho@gmail.com>2015-11-11 12:20:36 +0100
committerworktycho <work.tycho@gmail.com>2015-11-11 12:20:36 +0100
commitc001a99a68c91550bfa00195c68fcd33d09abafb (patch)
treea06cd75afd7d9f47590edeb84bf0c7741ff18422
parentMerge pull request #2634 from cuberite/vh (diff)
parentAvoid reading out of bounds (diff)
downloadcuberite-c001a99a68c91550bfa00195c68fcd33d09abafb.tar
cuberite-c001a99a68c91550bfa00195c68fcd33d09abafb.tar.gz
cuberite-c001a99a68c91550bfa00195c68fcd33d09abafb.tar.bz2
cuberite-c001a99a68c91550bfa00195c68fcd33d09abafb.tar.lz
cuberite-c001a99a68c91550bfa00195c68fcd33d09abafb.tar.xz
cuberite-c001a99a68c91550bfa00195c68fcd33d09abafb.tar.zst
cuberite-c001a99a68c91550bfa00195c68fcd33d09abafb.zip
-rw-r--r--src/Entities/Player.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index d6d890fdf..3bea60af7 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -462,7 +462,17 @@ void cPlayer::SetTouchGround(bool a_bTouchGround)
static const auto HalfWidth = GetWidth() / 2;
static const auto EPS = 0.0001;
- BLOCKTYPE BlockAtFoot = GetWorld()->GetBlock(POS_TOINT);
+ /* Since swimming is decided in a tick and is asynchronous to this, we have to check for dampeners ourselves.
+ The behaviour as of 1.8.8 is the following:
+ - Landing in water alleviates all fall damage
+ - Passing through any liquid (water + lava) and cobwebs "slows" the player down,
+ i.e. resets the fall distance to that block, but only after checking for fall damage
+ (this means that plummeting into lava will still kill the player via fall damage, although cobwebs
+ will slow players down enough to have multiple updates that keep them alive)
+
+ With this in mind, we first check the block at the player's feet, and decide which behaviour we want to go with.
+ */
+ BLOCKTYPE BlockAtFoot = (cChunkDef::IsValidHeight(GetPosY())) ? GetWorld()->GetBlock(POS_TOINT) : E_BLOCK_AIR;
bool IsFootInWater = IsBlockWater(BlockAtFoot);
bool IsFootInLiquid = IsFootInWater || IsBlockLava(BlockAtFoot) || (BlockAtFoot == E_BLOCK_COBWEB); // okay so cobweb is not _technically_ a liquid...
@@ -470,7 +480,7 @@ void cPlayer::SetTouchGround(bool a_bTouchGround)
!IsFlying() &&
(
(
- ((GetPosY() >= 1) && (GetPosY() <= 255) && ((GetPosY() - POSY_TOINT) <= EPS)) &&
+ (cChunkDef::IsValidHeight(GetPosY()) && ((GetPosY() - POSY_TOINT) <= EPS)) &&
(
cBlockInfo::IsSolid(GetWorld()->GetBlock((GetPosition() + Vector3d(0, -1, 0)).Floor())) ||
cBlockInfo::IsSolid(GetWorld()->GetBlock((GetPosition() + Vector3d(HalfWidth, -1, 0)).Floor())) ||
@@ -480,7 +490,7 @@ void cPlayer::SetTouchGround(bool a_bTouchGround)
)
) ||
(
- (((GetPosY() >= 1) && (GetPosY() <= 255) && GetPosY() >= POSY_TOINT) && ((GetPosY() - (POSY_TOINT + 0.5)) <= EPS)) &&
+ (cChunkDef::IsValidHeight(GetPosY()) && (GetPosY() >= POSY_TOINT) && ((GetPosY() - (POSY_TOINT + 0.5)) <= EPS)) &&
(
cBlockSlabHandler::IsAnySlabType(GetWorld()->GetBlock((GetPosition() + Vector3d(0, 0, 0)).Floor())) ||
cBlockSlabHandler::IsAnySlabType(GetWorld()->GetBlock((GetPosition() + Vector3d(HalfWidth, 0, 0)).Floor())) ||
@@ -490,7 +500,7 @@ void cPlayer::SetTouchGround(bool a_bTouchGround)
)
) ||
(
- ((GetPosY() >= 1) && (GetPosY() <= 255) && fmod(GetPosY(), 0.125) <= EPS) &&
+ (cChunkDef::IsValidHeight(GetPosY()) && (fmod(GetPosY(), 0.125) <= EPS)) &&
(
(GetWorld()->GetBlock((GetPosition() + Vector3d(0, 0, 0)).Floor()) == E_BLOCK_SNOW) ||
(GetWorld()->GetBlock((GetPosition() + Vector3d(HalfWidth, 0, 0)).Floor()) == E_BLOCK_SNOW) ||