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:
parent
f061840e83
commit
64a24a4c79
@ -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 =
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user