ClientHandle: Fix block interaction regressions (#5431)

* ClientHandle: Fix block interaction regressions

* Fix reach distance being halved.
* Fix fire extinguish not working, fixes #5422.

* AddFaceDirection: deprecate non-vector version
This commit is contained in:
Tiger Wang 2022-07-16 12:04:14 +01:00 committed by GitHub
parent f061840e83
commit 64a24a4c79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 79 deletions

View File

@ -14299,13 +14299,13 @@ end
Type = "number",
},
},
Notes = "Returns the coords of a block adjacent to the specified block through the specified {{Globals#BlockFaces|face}}",
Notes = "<b>OBSOLETE</b>, use the vector version instead.",
},
{
Params =
{
{
Name = "BlockPos",
Name = "Position",
Type = "Vector3i",
},
{
@ -14313,7 +14313,7 @@ end
Type = "eBlockFace",
},
{
Name = "IsInverse",
Name = "InvertDirection",
Type = "boolean",
IsOptional = true,
},
@ -14321,11 +14321,10 @@ end
Returns =
{
{
Name = "BlockPos",
Type = "Vector3i",
},
},
Notes = "Returns the coords of a block adjacent to the specified block through the specified {{Globals#BlockFaces|face}}",
Notes = "By default, returns the coordinates adjacent to the specified block through the specified face. If inverted, returns the coordinates adjacent to the opposite face.",
},
},
Base64Decode =

View File

@ -326,8 +326,10 @@ private:
static bool IsNotConnected(cChunkInterface & a_ChunkInterface, Vector3i a_Pos, eBlockFace a_BlockFace, char a_Pure = 0)
{
AddFaceDirection(a_Pos.x, a_Pos.y, a_Pos.z, a_BlockFace, false);
a_Pos = AddFaceDirection(a_Pos, a_BlockFace, false);
NIBBLETYPE Meta;
if (!IsBlockRail(a_ChunkInterface.GetBlock(a_Pos)))
{
if (!IsBlockRail(a_ChunkInterface.GetBlock(a_Pos + Vector3i(0, 1, 0))) || (a_Pure != E_PURE_UPDOWN))

View File

@ -1117,17 +1117,15 @@ void cClientHandle::HandleLeftClick(Vector3i a_BlockPos, eBlockFace a_BlockFace,
/* Check for clickthrough-blocks:
When the user breaks a fire block, the client send the wrong block location.
We must find the right block with the face direction. */
Vector3i BlockPos = a_BlockPos;
AddFaceDirection(BlockPos, a_BlockFace);
if (cChunkDef::IsValidHeight(BlockPos) && cBlockInfo::IsClickedThrough(m_Player->GetWorld()->GetBlock(BlockPos)))
if (
const auto InterferingPosition = AddFaceDirection(a_BlockPos, a_BlockFace);
cChunkDef::IsValidHeight(InterferingPosition) && cBlockInfo::IsClickedThrough(m_Player->GetWorld()->GetBlock(InterferingPosition))
)
{
a_BlockPos = BlockPos;
a_BlockPos = InterferingPosition;
}
constexpr double MaxBlockDistance = 6.0;
if (!cBoundingBox(m_Player->GetPosition(), MaxBlockDistance).IsInside(a_BlockPos))
if (!IsWithinReach(a_BlockPos))
{
m_Player->SendBlocksAround(a_BlockPos, 2);
return;
@ -1270,13 +1268,6 @@ void cClientHandle::HandleBlockDigStarted(Vector3i a_BlockPos, eBlockFace a_Bloc
return;
}
constexpr double MaxBlockDistance = 6.0;
if (!cBoundingBox(m_Player->GetPosition(), MaxBlockDistance).IsInside(a_BlockPos))
{
m_Player->SendBlocksAround(a_BlockPos, 2);
return;
}
// Set the last digging coords to the block being dug, so that they can be checked in DIG_FINISHED to avoid dig / aim bug in the client:
m_HasStartedDigging = true;
m_LastDigBlockPos = a_BlockPos;
@ -1439,27 +1430,13 @@ void cClientHandle::HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace
// TODO: We are still consuming the items in main hand. Remove this override when the off-hand consumption is handled correctly.
a_UsedMainHand = true;
const cItem & HeldItem = a_UsedMainHand ? m_Player->GetEquippedItem() : m_Player->GetInventory().GetShieldSlot();
// Distance from the block's center to the player's eye height.
const double Dist = (Vector3d(0.5, 0.5, 0.5) + a_BlockPos - m_Player->GetEyePosition()).SqrLength();
// Check the reach distance:
// _X 2014-11-25: I've maxed at 5.26 with a Survival client and 5.78 with a Creative client in my tests
double MaxDist = m_Player->IsGameModeCreative() ? 33.4084 : 27.6676;
bool IsWithinReach = (Dist <= MaxDist);
FLOGD("HandleRightClick: {0}, face {1}, Cursor {2}, Hand: {3}, HeldItem: {4}; Dist: {5:.02f}",
a_BlockPos, a_BlockFace, a_CursorPos, a_UsedMainHand, ItemToFullString(HeldItem), Dist
);
cWorld * World = m_Player->GetWorld();
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
const cItem & HeldItem = a_UsedMainHand ? m_Player->GetEquippedItem() : m_Player->GetInventory().GetShieldSlot();
if (
!PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockPos, a_BlockFace, a_CursorPos) &&
IsWithinReach && !m_Player->IsFrozen()
)
FLOGD("HandleRightClick: {0}, face {1}, Cursor {2}, Hand: {3}, HeldItem: {4}", a_BlockPos, a_BlockFace, a_CursorPos, a_UsedMainHand, ItemToFullString(HeldItem));
if (!PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockPos, a_BlockFace, a_CursorPos) && IsWithinReach(a_BlockPos) && !m_Player->IsFrozen())
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
@ -2101,6 +2078,19 @@ bool cClientHandle::CheckBlockInteractionsRate(void)
bool cClientHandle::IsWithinReach(const Vector3i a_Position) const
{
// Distance from the block's center to the player's eye height.
const double Distance = (Vector3d(0.5, 0.5, 0.5) + a_Position - m_Player->GetEyePosition()).SqrLength();
// _X 2014-11-25: I've maxed at 5.26 with a Survival client and 5.78 with a Creative client in my tests.
return Distance <= (m_Player->IsGameModeCreative() ? 33.4084 : 27.6676);
}
void cClientHandle::Tick(std::chrono::milliseconds a_Dt)
{
using namespace std::chrono_literals;

View File

@ -581,6 +581,9 @@ private:
/** Returns true if the rate block interactions is within a reasonable limit (bot protection) */
bool CheckBlockInteractionsRate(void);
/** Returns whether the player could in fact reach the position they're attempting to interact with. */
bool IsWithinReach(Vector3i a_Position) const;
/** Adds a single chunk to be streamed to the client; used by StreamChunks() */
void StreamChunk(int a_ChunkX, int a_ChunkZ, cChunkSender::Priority a_Priority);

View File

@ -377,42 +377,34 @@ eDamageType StringToDamageType(const AString & a_DamageTypeString)
void AddFaceDirection(int & a_BlockX, int & a_BlockY, int & a_BlockZ, eBlockFace a_BlockFace, bool a_bInverse)
{
if (!a_bInverse)
LOGWARNING("AddFaceDirection with X/Y/Z parameters is deprecated, use the vector version");
const auto Offset = AddFaceDirection({ a_BlockX, a_BlockY, a_BlockZ }, a_BlockFace, a_bInverse);
a_BlockX = Offset.x;
a_BlockY = Offset.y;
a_BlockZ = Offset.z;
}
Vector3i AddFaceDirection(const Vector3i a_Position, const eBlockFace a_BlockFace, const bool a_InvertDirection)
{
const int Offset = a_InvertDirection ? -1 : 1;
switch (a_BlockFace)
{
switch (a_BlockFace)
{
case BLOCK_FACE_YP: a_BlockY++; break;
case BLOCK_FACE_YM: a_BlockY--; break;
case BLOCK_FACE_ZM: a_BlockZ--; break;
case BLOCK_FACE_ZP: a_BlockZ++; break;
case BLOCK_FACE_XP: a_BlockX++; break;
case BLOCK_FACE_XM: a_BlockX--; break;
case BLOCK_FACE_NONE:
{
LOGWARNING("%s: Unknown face: %d", __FUNCTION__, a_BlockFace);
ASSERT(!"AddFaceDirection(): Unknown face");
break;
}
}
}
else
{
switch (a_BlockFace)
{
case BLOCK_FACE_YP: a_BlockY--; break;
case BLOCK_FACE_YM: a_BlockY++; break;
case BLOCK_FACE_ZM: a_BlockZ++; break;
case BLOCK_FACE_ZP: a_BlockZ--; break;
case BLOCK_FACE_XP: a_BlockX--; break;
case BLOCK_FACE_XM: a_BlockX++; break;
case BLOCK_FACE_NONE:
{
LOGWARNING("%s: Unknown inv face: %d", __FUNCTION__, a_BlockFace);
ASSERT(!"AddFaceDirection(): Unknown face");
break;
}
}
case BLOCK_FACE_YP: return a_Position.addedY(+Offset);
case BLOCK_FACE_YM: return a_Position.addedY(-Offset);
case BLOCK_FACE_ZM: return a_Position.addedZ(-Offset);
case BLOCK_FACE_ZP: return a_Position.addedZ(+Offset);
case BLOCK_FACE_XP: return a_Position.addedX(+Offset);
case BLOCK_FACE_XM: return a_Position.addedX(-Offset);
case BLOCK_FACE_NONE: break;
}
UNREACHABLE("Unsupported block face");
}

View File

@ -570,12 +570,8 @@ If a_Inverse is true, the opposite direction is used instead. */
void AddFaceDirection(int & a_BlockX, int & a_BlockY, int & a_BlockZ, eBlockFace a_BlockFace, bool a_bInverse = false);
/** Returns the coords of a block that is neighboring the specified position through its specified face.
If a_IsInverse is true, the opposite direction is used instead. */
inline Vector3i AddFaceDirection(Vector3i a_Pos, eBlockFace a_BlockFace, bool a_bInverse = false)
{
AddFaceDirection(a_Pos.x, a_Pos.y, a_Pos.z, a_BlockFace, a_bInverse);
return a_Pos;
}
If a_InvertDirection is true, the opposite direction is used instead. */
Vector3i AddFaceDirection(Vector3i a_Pos, eBlockFace a_BlockFace, bool a_InvertDirection = false);
// tolua_end