From 66e65898838e3d5d40dfb225fd6c34f0f354b2e3 Mon Sep 17 00:00:00 2001 From: Gargaj Date: Tue, 10 Nov 2015 14:02:07 +0100 Subject: blockheight mechanism --- src/Entities/Player.cpp | 97 ------------------------------------------------- 1 file changed, 97 deletions(-) (limited to 'src/Entities/Player.cpp') diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 3bea60af7..33ded6ab9 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -55,8 +55,6 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) : m_FoodSaturationLevel(5.0), m_FoodTickTimer(0), m_FoodExhaustionLevel(0.0), - m_LastGroundHeight(0), - m_bTouchGround(false), m_Stance(0.0), m_Inventory(*this), m_EnderChestContents(9, 3), @@ -451,101 +449,6 @@ void cPlayer::SetTouchGround(bool a_bTouchGround) return; } - /* Not pretty looking, and is more suited to wherever server-sided collision detection is implemented. - The following condition sets on-ground-ness if - The player isn't swimming or flying (client hardcoded conditions) and - they're on a block (Y is exact) - ensure any they could be standing on (including on the edges) is solid or - they're on a slab (Y significand is 0.5) - ditto with slab check - they're on a snow layer (Y divisible by 0.125) - ditto with snow layer check - */ - - static const auto HalfWidth = GetWidth() / 2; - static const auto EPS = 0.0001; - - /* 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... - - if ( - !IsFlying() && - ( - ( - (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())) || - cBlockInfo::IsSolid(GetWorld()->GetBlock((GetPosition() + Vector3d(-HalfWidth, -1, 0)).Floor())) || - cBlockInfo::IsSolid(GetWorld()->GetBlock((GetPosition() + Vector3d(0, -1, HalfWidth)).Floor())) || - cBlockInfo::IsSolid(GetWorld()->GetBlock((GetPosition() + Vector3d(0, -1, -HalfWidth)).Floor())) - ) - ) || - ( - (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())) || - cBlockSlabHandler::IsAnySlabType(GetWorld()->GetBlock((GetPosition() + Vector3d(-HalfWidth, 0, 0)).Floor())) || - cBlockSlabHandler::IsAnySlabType(GetWorld()->GetBlock((GetPosition() + Vector3d(0, 0, HalfWidth)).Floor())) || - cBlockSlabHandler::IsAnySlabType(GetWorld()->GetBlock((GetPosition() + Vector3d(0, 0, -HalfWidth)).Floor())) - ) - ) || - ( - (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) || - (GetWorld()->GetBlock((GetPosition() + Vector3d(-HalfWidth, 0, 0)).Floor()) == E_BLOCK_SNOW) || - (GetWorld()->GetBlock((GetPosition() + Vector3d(0, 0, HalfWidth)).Floor()) == E_BLOCK_SNOW) || - (GetWorld()->GetBlock((GetPosition() + Vector3d(0, 0, -HalfWidth)).Floor()) == E_BLOCK_SNOW) - ) - ) - ) - ) - { - auto Damage = static_cast(m_LastGroundHeight - GetPosY() - 3.0); - if ((Damage > 0) && !IsFootInWater) - { - // cPlayer makes sure damage isn't applied in creative, no need to check here - TakeDamage(dtFalling, nullptr, Damage, Damage, 0); - - // Fall particles - Damage = std::min(15, Damage); - GetClientHandle()->SendParticleEffect( - "blockdust", - GetPosition(), - { 0, 0, 0 }, - (Damage - 1.f) * ((0.3f - 0.1f) / (15.f - 1.f)) + 0.1f, // Map damage (1 - 15) to particle speed (0.1 - 0.3) - static_cast((Damage - 1.f) * ((50.f - 20.f) / (15.f - 1.f)) + 20.f), // Map damage (1 - 15) to particle quantity (20 - 50) - { { GetWorld()->GetBlock(POS_TOINT - Vector3i(0, 1, 0)), 0 } } - ); - } - - m_bTouchGround = true; - m_LastGroundHeight = GetPosY(); - } - else - { - m_bTouchGround = false; - } - - /* Note: it is currently possible to fall through lava and still die from fall damage - because of the client skipping an update about the lava block. This can only be resolved by - interpolating between positions. */ - if (IsFlying() || IsFootInLiquid || IsClimbing()) - { - m_LastGroundHeight = GetPosY(); - } - UNUSED(a_bTouchGround); /* Unfortunately whatever the reason, there are still desyncs in on-ground status between the client and server. For example: 1. Walking off a ledge (whatever height) -- cgit v1.2.3