Valid Height is now checked by vector.

This commit is contained in:
x12xx12x 2022-04-20 00:10:35 +02:00 committed by Alexander Harkness
parent 5ea7675eca
commit fe983a1a45
44 changed files with 202 additions and 211 deletions

View File

@ -500,7 +500,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
}
#endif
{
bool res = self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4, Player);
bool res = self->SetSignLines({BlockX, BlockY, BlockZ}, Line1, Line2, Line3, Line4, Player);
tolua_pushboolean(LuaState, res ? 1 : 0);
}
}

View File

@ -1638,7 +1638,7 @@ static int tolua_cPlayer_PlaceBlock(lua_State * tolua_S)
NIBBLETYPE BlockMeta;
L.GetStackValues(1, Self, Position, BlockType, BlockMeta);
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'position'");
}

View File

@ -747,7 +747,7 @@ static int tolua_cWorld_FastSetBlock(lua_State * tolua_S)
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
}
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'position'");
}
@ -903,7 +903,7 @@ static int tolua_cWorld_GetBlock(lua_State * tolua_S)
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
}
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
L.Push(E_BLOCK_AIR);
return 1;
@ -959,7 +959,7 @@ static int tolua_cWorld_GetBlockBlockLight(lua_State * tolua_S)
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
}
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'position'");
}
@ -1016,7 +1016,7 @@ static int tolua_cWorld_GetBlockInfo(lua_State * tolua_S)
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
}
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'position'");
}
@ -1083,7 +1083,7 @@ static int tolua_cWorld_GetBlockMeta(lua_State * tolua_S)
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
}
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
L.Push(0);
return 1;
@ -1139,7 +1139,7 @@ static int tolua_cWorld_GetBlockSkyLight(lua_State * tolua_S)
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
}
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'position'");
}
@ -1196,7 +1196,7 @@ static int tolua_cWorld_GetBlockTypeMeta(lua_State * tolua_S)
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
}
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
L.Push(E_BLOCK_AIR, 0);
return 2;
@ -1470,7 +1470,7 @@ static int tolua_cWorld_SetBlock(lua_State * tolua_S)
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
}
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'position'");
}
@ -1528,7 +1528,7 @@ static int tolua_cWorld_SetBlockMeta(lua_State * tolua_S)
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'self'");
}
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Invalid 'position'");
}
@ -1570,7 +1570,7 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S)
}
// Call the function:
bool res = Self->SetSignLines(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
bool res = Self->SetSignLines({BlockX, BlockY, BlockZ}, Line1, Line2, Line3, Line4);
// Push the returned values:
L.Push(res);

View File

@ -445,8 +445,8 @@ bool cBlockArea::IsValidCoords(const Vector3i & a_Coords) const
bool cBlockArea::Read(cForEachChunkProvider & a_ForEachChunkProvider, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes)
{
ASSERT(IsValidDataTypeCombination(a_DataTypes));
ASSERT(cChunkDef::IsValidHeight(a_MinBlockY));
ASSERT(cChunkDef::IsValidHeight(a_MaxBlockY));
ASSERT(cChunkDef::IsValidHeight({a_MinBlockX, a_MinBlockY, a_MinBlockZ}));
ASSERT(cChunkDef::IsValidHeight({a_MaxBlockX, a_MaxBlockY, a_MaxBlockZ}));
ASSERT(a_MinBlockX <= a_MaxBlockX);
ASSERT(a_MinBlockY <= a_MaxBlockY);
ASSERT(a_MinBlockZ <= a_MaxBlockZ);
@ -518,8 +518,8 @@ bool cBlockArea::Read(cForEachChunkProvider & a_ForEachChunkProvider, const Vect
bool cBlockArea::Write(cForEachChunkProvider & a_ForEachChunkProvider, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes)
{
ASSERT((a_DataTypes & GetDataTypes()) == a_DataTypes); // Are you requesting only the data that I have?
ASSERT(cChunkDef::IsValidHeight(a_MinBlockY));
ASSERT(cChunkDef::IsValidHeight(a_MinBlockY + m_Size.y - 1));
ASSERT(cChunkDef::IsValidHeight({a_MinBlockX, a_MinBlockY, a_MinBlockZ}));
ASSERT(cChunkDef::IsValidHeight({a_MinBlockX, a_MinBlockY + m_Size.y - 1, a_MinBlockZ}));
return a_ForEachChunkProvider.WriteBlockArea(*this, a_MinBlockX, a_MinBlockY, a_MinBlockZ, a_DataTypes);
}

View File

@ -16,7 +16,7 @@ cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i
Super(a_BlockType, a_BlockMeta, a_Pos, a_World)
{
ASSERT((a_BlockType == E_BLOCK_WALLSIGN) || (a_BlockType == E_BLOCK_SIGN_POST));
ASSERT(cChunkDef::IsValidHeight(a_Pos.y));
ASSERT(cChunkDef::IsValidHeight(a_Pos));
}

View File

@ -127,7 +127,7 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
auto SupportRelPos = AddFaceDirection(a_Position, BlockMetaDataToBlockFace(a_Meta), true);
if (!cChunkDef::IsValidHeight(SupportRelPos.y))
if (!cChunkDef::IsValidHeight(SupportRelPos))
{
return false;
}

View File

@ -61,7 +61,7 @@ private:
}
// Farmland too dry. If nothing is growing on top, turn back to dirt:
auto UpperBlock = cChunkDef::IsValidHeight(a_RelPos.y + 1) ? a_Chunk.GetBlock(a_RelPos.addedY(1)) : E_BLOCK_AIR;
auto UpperBlock = cChunkDef::IsValidHeight(a_RelPos.addedY(1)) ? a_Chunk.GetBlock(a_RelPos.addedY(1)) : E_BLOCK_AIR;
switch (UpperBlock)
{
case E_BLOCK_BEETROOTS:

View File

@ -88,7 +88,7 @@ private:
// Check if it's fuel:
BLOCKTYPE BlockType;
if (
!cChunkDef::IsValidHeight(Pos.y) ||
!cChunkDef::IsValidHeight(Pos) ||
!a_Chunk.UnboundedRelGetBlockType(Pos, BlockType) ||
!cFireSimulator::IsFuel(BlockType)
)
@ -110,7 +110,7 @@ private:
{
auto NeighborPos = Pos + CrossCoords[i];
if (
cChunkDef::IsValidHeight(NeighborPos.y) &&
cChunkDef::IsValidHeight(NeighborPos) &&
a_Chunk.UnboundedRelGetBlockType(NeighborPos, BlockType) &&
(BlockType == E_BLOCK_AIR)
)

View File

@ -99,7 +99,7 @@ private:
static Survivability DetermineSurvivability(cChunk & a_Chunk, const Vector3i a_RelPos)
{
const auto AbovePos = a_RelPos.addedY(1);
if (!cChunkDef::IsValidHeight(AbovePos.y))
if (!cChunkDef::IsValidHeight(AbovePos))
{
return Survivability::CanSpread;
}
@ -126,7 +126,7 @@ private:
/** Attempt to spread grass to a block at the given position. */
static void TrySpreadTo(cChunk & a_Chunk, Vector3i a_RelPos)
{
if (!cChunkDef::IsValidHeight(a_RelPos.y))
if (!cChunkDef::IsValidHeight(a_RelPos))
{
// Y Coord out of range
return;

View File

@ -486,7 +486,7 @@ void cBlockHandler::OnNeighborChanged(cChunkInterface & a_ChunkInterface, Vector
void cBlockHandler::NeighborChanged(cChunkInterface & a_ChunkInterface, Vector3i a_NeighborPos, eBlockFace a_WhichNeighbor)
{
if (!cChunkDef::IsValidHeight(a_NeighborPos.y))
if (!cChunkDef::IsValidHeight(a_NeighborPos))
{
return;
}

View File

@ -94,7 +94,7 @@ private:
// Find the type of block the lever is attached to:
auto NeighborFace = BlockMetaDataToBlockFace(a_Meta);
auto NeighborPos = AddFaceDirection(a_Position, NeighborFace, true);
if (!cChunkDef::IsValidHeight(NeighborPos.y))
if (!cChunkDef::IsValidHeight(NeighborPos))
{
return false;
}

View File

@ -31,7 +31,7 @@ private:
virtual bool CanBeAt(const cChunk & a_Chunk, const Vector3i a_Position, const NIBBLETYPE a_Meta) const override
{
auto UnderPos = a_Position.addedY(-1);
if (!cChunkDef::IsValidHeight(UnderPos.y))
if (!cChunkDef::IsValidHeight(UnderPos))
{
return false;
}

View File

@ -215,7 +215,7 @@ bool cBlockPistonHandler::CanPushBlock(
Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir
)
{
if (!cChunkDef::IsValidHeight(a_BlockPos.y))
if (!cChunkDef::IsValidHeight(a_BlockPos))
{
// Can't push a void block.
return false;
@ -299,7 +299,7 @@ void cBlockPistonHandler::OnBroken(
const auto Extension = a_BlockPos + MetadataToOffset(a_OldBlockMeta);
if (
cChunkDef::IsValidHeight(Extension.y) &&
cChunkDef::IsValidHeight(Extension) &&
(a_ChunkInterface.GetBlock(Extension) == E_BLOCK_PISTON_EXTENSION)
)
{
@ -324,7 +324,7 @@ void cBlockPistonHeadHandler::OnBroken(
{
UNUSED(a_Digger);
const auto Base = a_BlockPos - cBlockPistonHandler::MetadataToOffset(a_OldBlockMeta);
if (!cChunkDef::IsValidHeight(Base.y))
if (!cChunkDef::IsValidHeight(Base))
{
return;
}

View File

@ -199,7 +199,7 @@ private:
// Vine cannot grow down if at the bottom:
auto GrowPos = a_RelPos.addedY(-1);
if (!cChunkDef::IsValidHeight(GrowPos.y))
if (!cChunkDef::IsValidHeight(GrowPos))
{
return;
}

View File

@ -1022,7 +1022,7 @@ int cChunk::GrowPlantAt(Vector3i a_RelPos, int a_NumStages)
bool cChunk::UnboundedRelGetBlock(Vector3i a_RelPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const
{
if (!cChunkDef::IsValidHeight(a_RelPos.y))
if (!cChunkDef::IsValidHeight(a_RelPos))
{
LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.y);
return false;
@ -1043,7 +1043,7 @@ bool cChunk::UnboundedRelGetBlock(Vector3i a_RelPos, BLOCKTYPE & a_BlockType, NI
bool cChunk::UnboundedRelGetBlockType(Vector3i a_RelPos, BLOCKTYPE & a_BlockType) const
{
if (!cChunkDef::IsValidHeight(a_RelPos.y))
if (!cChunkDef::IsValidHeight(a_RelPos))
{
LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.y);
return false;
@ -1064,7 +1064,7 @@ bool cChunk::UnboundedRelGetBlockType(Vector3i a_RelPos, BLOCKTYPE & a_BlockType
bool cChunk::UnboundedRelGetBlockMeta(Vector3i a_RelPos, NIBBLETYPE & a_BlockMeta) const
{
if (!cChunkDef::IsValidHeight(a_RelPos.y))
if (!cChunkDef::IsValidHeight(a_RelPos))
{
LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.y);
return false;
@ -1085,7 +1085,7 @@ bool cChunk::UnboundedRelGetBlockMeta(Vector3i a_RelPos, NIBBLETYPE & a_BlockMet
bool cChunk::UnboundedRelGetBlockBlockLight(Vector3i a_RelPos, NIBBLETYPE & a_BlockBlockLight) const
{
if (!cChunkDef::IsValidHeight(a_RelPos.y))
if (!cChunkDef::IsValidHeight(a_RelPos))
{
LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.y);
return false;
@ -1106,7 +1106,7 @@ bool cChunk::UnboundedRelGetBlockBlockLight(Vector3i a_RelPos, NIBBLETYPE & a_Bl
bool cChunk::UnboundedRelGetBlockSkyLight(Vector3i a_RelPos, NIBBLETYPE & a_BlockSkyLight) const
{
if (!cChunkDef::IsValidHeight(a_RelPos.y))
if (!cChunkDef::IsValidHeight(a_RelPos))
{
LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.y);
return false;
@ -1127,7 +1127,7 @@ bool cChunk::UnboundedRelGetBlockSkyLight(Vector3i a_RelPos, NIBBLETYPE & a_Bloc
bool cChunk::UnboundedRelGetBlockLights(Vector3i a_RelPos, NIBBLETYPE & a_BlockLight, NIBBLETYPE & a_SkyLight) const
{
if (!cChunkDef::IsValidHeight(a_RelPos.y))
if (!cChunkDef::IsValidHeight(a_RelPos))
{
LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.y);
return false;
@ -1149,7 +1149,7 @@ bool cChunk::UnboundedRelGetBlockLights(Vector3i a_RelPos, NIBBLETYPE & a_BlockL
bool cChunk::UnboundedRelSetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
if (!cChunkDef::IsValidHeight(a_RelPos.y))
if (!cChunkDef::IsValidHeight(a_RelPos))
{
LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.y);
return false;
@ -1170,7 +1170,7 @@ bool cChunk::UnboundedRelSetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBB
bool cChunk::UnboundedRelFastSetBlock(Vector3i a_RelPos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
if (!cChunkDef::IsValidHeight(a_RelPos.y))
if (!cChunkDef::IsValidHeight(a_RelPos))
{
LOGWARNING("%s: requesting a block with a_RelY out of range: %d", __FUNCTION__, a_RelPos.y);
return false;

View File

@ -164,15 +164,10 @@ public:
}
/** Validates a height-coordinate. Returns false if height-coordiante is out of height bounds */
inline static bool IsValidHeight(int a_Height)
{
return ((a_Height >= 0) && (a_Height < Height));
}
/** Validates a height-coordinate. Returns false if height-coordinate is out of height bounds */
inline static bool IsValidHeight(Vector3i a_BlockPosition)
{
return IsValidHeight(a_BlockPosition.y);
return ((a_BlockPosition.y >= 0) && (a_BlockPosition.y < Height));
}
@ -188,7 +183,7 @@ public:
{
return (
IsValidWidth(a_RelPos.x) &&
IsValidHeight(a_RelPos.y) &&
IsValidHeight(a_RelPos) &&
IsValidWidth(a_RelPos.z)
);
}

View File

@ -748,7 +748,7 @@ bool cChunkMap::GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure)
res = false;
continue;
}
if (!cChunkDef::IsValidHeight(itr->m_RelY))
if (!cChunkDef::IsValidHeight(itr->GetRelativePos()))
{
continue;
}

View File

@ -61,6 +61,8 @@ int cClientHandle::s_ClientCount = 0;
float cClientHandle::FASTBREAK_PERCENTAGE;
Vector3i cClientHandle::s_IllegalPosition = {0, cChunkDef::Height + 1, 0};
////////////////////////////////////////////////////////////////////////////////
@ -81,16 +83,16 @@ cClientHandle::cClientHandle(const AString & a_IPString, int a_ViewDistance) :
m_PingID(1),
m_BlockDigAnimStage(-1),
m_BlockDigAnimSpeed(0),
m_BlockDigAnimPos(),
m_BlockDigAnimPos(s_IllegalPosition),
m_HasStartedDigging(false),
m_LastDigBlockPos(),
m_LastDigBlockPos(s_IllegalPosition),
m_State(csConnected),
m_NumExplosionsThisTick(0),
m_NumBlockChangeInteractionsThisTick(0),
m_UniqueID(0),
m_HasSentPlayerChunk(false),
m_Locale("en_GB"),
m_LastPlacedSign(0, -1, 0),
m_LastPlacedSign(s_IllegalPosition),
m_ProtocolVersion(0)
{
s_ClientCount++; // Not protected by CS because clients are always constructed from the same thread
@ -1119,16 +1121,13 @@ void cClientHandle::HandleLeftClick(Vector3i a_BlockPos, eBlockFace a_BlockFace,
Vector3i BlockPos = a_BlockPos;
AddFaceDirection(BlockPos, a_BlockFace);
if (cChunkDef::IsValidHeight(BlockPos.y) && cBlockInfo::IsClickedThrough(m_Player->GetWorld()->GetBlock(BlockPos)))
if (cChunkDef::IsValidHeight(BlockPos) && cBlockInfo::IsClickedThrough(m_Player->GetWorld()->GetBlock(BlockPos)))
{
a_BlockPos = BlockPos;
}
if (
(Diff(m_Player->GetPosX(), static_cast<double>(a_BlockPos.x)) > 6) ||
(Diff(m_Player->GetPosY(), static_cast<double>(a_BlockPos.y)) > 6) ||
(Diff(m_Player->GetPosZ(), static_cast<double>(a_BlockPos.z)) > 6)
)
constexpr double MaxBlockDistance = 6.0;
if (!cBoundingBox(m_Player->GetPosition(), MaxBlockDistance).IsInside(a_BlockPos))
{
m_Player->SendBlocksAround(a_BlockPos, 2);
return;
@ -1176,11 +1175,11 @@ void cClientHandle::HandleLeftClick(Vector3i a_BlockPos, eBlockFace a_BlockFace,
// When bow is in off-hand / shield slot
if (m_Player->GetInventory().GetShieldSlot().m_ItemType == E_ITEM_BOW)
{
m_Player->GetInventory().GetShieldSlot().GetHandler().OnItemShoot(m_Player, {a_BlockPos}, a_BlockFace);
m_Player->GetInventory().GetShieldSlot().GetHandler().OnItemShoot(m_Player, a_BlockPos, a_BlockFace);
}
else
{
ItemHandler.OnItemShoot(m_Player, {a_BlockPos}, a_BlockFace);
ItemHandler.OnItemShoot(m_Player, a_BlockPos, a_BlockFace);
}
}
return;
@ -1271,11 +1270,8 @@ void cClientHandle::HandleBlockDigStarted(Vector3i a_BlockPos, eBlockFace a_Bloc
return;
}
if (
(Diff(m_Player->GetPosX(), static_cast<double>(a_BlockPos.x)) > 6) ||
(Diff(m_Player->GetPosY(), static_cast<double>(a_BlockPos.y)) > 6) ||
(Diff(m_Player->GetPosZ(), static_cast<double>(a_BlockPos.z)) > 6)
)
constexpr double MaxBlockDistance = 6.0;
if (!cBoundingBox(m_Player->GetPosition(), MaxBlockDistance).IsInside(a_BlockPos))
{
m_Player->SendBlocksAround(a_BlockPos, 2);
return;
@ -1309,9 +1305,9 @@ void cClientHandle::HandleBlockDigStarted(Vector3i a_BlockPos, eBlockFace a_Bloc
cWorld * World = m_Player->GetWorld();
cChunkInterface ChunkInterface(World->GetChunkMap());
cBlockHandler::For(DiggingBlock).OnDigging(ChunkInterface, *World, *m_Player, {a_BlockPos});
cBlockHandler::For(DiggingBlock).OnDigging(ChunkInterface, *World, *m_Player, a_BlockPos);
m_Player->GetEquippedItem().GetHandler().OnDiggingBlock(World, m_Player, m_Player->GetEquippedItem(), {a_BlockPos}, a_BlockFace);
m_Player->GetEquippedItem().GetHandler().OnDiggingBlock(World, m_Player, m_Player->GetEquippedItem(), a_BlockPos, a_BlockFace);
}
@ -1337,7 +1333,7 @@ void cClientHandle::HandleBlockDigFinished(Vector3i a_BlockPos, eBlockFace a_Blo
BLOCKTYPE DugBlock;
NIBBLETYPE DugMeta;
m_Player->GetWorld()->GetBlockTypeMeta({ a_BlockPos }, DugBlock, DugMeta);
m_Player->GetWorld()->GetBlockTypeMeta(a_BlockPos, DugBlock, DugMeta);
if (!m_Player->IsGameModeCreative())
{
@ -1411,14 +1407,14 @@ void cClientHandle::FinishDigAnimation()
m_Player->GetWorld()->BroadcastBlockBreakAnimation(static_cast<UInt32>(m_UniqueID), m_LastDigBlockPos, 10, this);
}
m_LastDigBlockPos = {-1, -1, -1};
m_LastDigBlockPos = s_IllegalPosition;
}
void cClientHandle::HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, bool a_UsedMainHand)
void cClientHandle::HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_CursorPos, bool a_UsedMainHand)
{
/* This function handles three actions:
(1) Place a block;
@ -1443,12 +1439,10 @@ 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 Vector3i ClickedPosition(a_BlockPos);
const Vector3i CursorPosition(a_CursorX, a_CursorY, a_CursorZ);
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) + ClickedPosition - m_Player->GetEyePosition()).SqrLength();
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
@ -1456,21 +1450,21 @@ void cClientHandle::HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace
bool IsWithinReach = (Dist <= MaxDist);
FLOGD("HandleRightClick: {0}, face {1}, Cursor {2}, Hand: {3}, HeldItem: {4}; Dist: {5:.02f}",
ClickedPosition, a_BlockFace, CursorPosition, a_UsedMainHand, ItemToFullString(HeldItem), Dist
a_BlockPos, a_BlockFace, a_CursorPos, a_UsedMainHand, ItemToFullString(HeldItem), Dist
);
cWorld * World = m_Player->GetWorld();
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
if (
!PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockPos, a_BlockFace, CursorPosition) &&
!PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockPos, a_BlockFace, a_CursorPos) &&
IsWithinReach && !m_Player->IsFrozen()
)
{
BLOCKTYPE BlockType;
NIBBLETYPE BlockMeta;
if (!World->GetBlockTypeMeta(ClickedPosition, BlockType, BlockMeta))
if (!World->GetBlockTypeMeta(a_BlockPos, BlockType, BlockMeta))
{
return;
}
@ -1484,12 +1478,12 @@ void cClientHandle::HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace
if (BlockUsable)
{
cChunkInterface ChunkInterface(World->GetChunkMap());
if (!PlgMgr->CallHookPlayerUsingBlock(*m_Player, a_BlockPos, a_BlockFace, CursorPosition, BlockType, BlockMeta))
if (!PlgMgr->CallHookPlayerUsingBlock(*m_Player, a_BlockPos, a_BlockFace, a_CursorPos, BlockType, BlockMeta))
{
// Use a block:
if (BlockHandler.OnUse(ChunkInterface, *World, *m_Player, ClickedPosition, a_BlockFace, CursorPosition))
if (BlockHandler.OnUse(ChunkInterface, *World, *m_Player, a_BlockPos, a_BlockFace, a_CursorPos))
{
PlgMgr->CallHookPlayerUsedBlock(*m_Player, a_BlockPos, a_BlockFace, CursorPosition, BlockType, BlockMeta);
PlgMgr->CallHookPlayerUsedBlock(*m_Player, a_BlockPos, a_BlockFace, a_CursorPos, BlockType, BlockMeta);
return; // Block use was successful, we're done.
}
@ -1497,7 +1491,7 @@ void cClientHandle::HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace
if (ItemPlaceable)
{
// Place a block:
ItemHandler.OnPlayerPlace(*m_Player, HeldItem, ClickedPosition, BlockType, BlockMeta, a_BlockFace, CursorPosition);
ItemHandler.OnPlayerPlace(*m_Player, HeldItem, a_BlockPos, BlockType, BlockMeta, a_BlockFace, a_CursorPos);
}
return;
@ -1514,19 +1508,19 @@ void cClientHandle::HandleRightClick(Vector3i a_BlockPos, eBlockFace a_BlockFace
}
// Place a block:
ItemHandler.OnPlayerPlace(*m_Player, HeldItem, ClickedPosition, BlockType, BlockMeta, a_BlockFace, CursorPosition);
ItemHandler.OnPlayerPlace(*m_Player, HeldItem, a_BlockPos, BlockType, BlockMeta, a_BlockFace, a_CursorPos);
return;
}
else if (ItemUseable)
{
if (!PlgMgr->CallHookPlayerUsingItem(*m_Player, a_BlockPos, a_BlockFace, CursorPosition))
if (!PlgMgr->CallHookPlayerUsingItem(*m_Player, a_BlockPos, a_BlockFace, a_CursorPos))
{
// All plugins agree with using the item.
// Use an item in hand with a target block.
cBlockInServerPluginInterface PluginInterface(*World);
ItemHandler.OnItemUse(World, m_Player, PluginInterface, HeldItem, ClickedPosition, a_BlockFace);
PlgMgr->CallHookPlayerUsedItem(*m_Player, a_BlockPos, a_BlockFace, CursorPosition);
ItemHandler.OnItemUse(World, m_Player, PluginInterface, HeldItem, a_BlockPos, a_BlockFace);
PlgMgr->CallHookPlayerUsedItem(*m_Player, a_BlockPos, a_BlockFace, a_CursorPos);
return;
}
}
@ -1609,9 +1603,8 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO
void cClientHandle::HandlePlayerMove(double a_PosX, double a_PosY, double a_PosZ, bool a_IsOnGround)
void cClientHandle::HandlePlayerMove(Vector3d a_Pos, bool a_IsOnGround)
{
const Vector3d NewPosition(a_PosX, a_PosY, a_PosZ);
const Vector3d OldPosition = GetPlayer()->GetPosition();
const auto PreviousIsOnGround = GetPlayer()->IsOnGround();
@ -1621,7 +1614,7 @@ void cClientHandle::HandlePlayerMove(double a_PosX, double a_PosY, double a_PosZ
#endif
if (
(OldPosition == NewPosition) &&
(OldPosition == a_Pos) &&
(PreviousIsOnGround == a_IsOnGround)
)
{
@ -1641,14 +1634,14 @@ void cClientHandle::HandlePlayerMove(double a_PosX, double a_PosY, double a_PosZ
}
// If the player has moved too far, "repair" them:
if ((OldPosition - NewPosition).SqrLength() > 100 * 100)
if ((OldPosition - a_Pos).SqrLength() > 100 * 100)
{
LOGD("Too far away (%0.2f), \"repairing\" the client", (OldPosition - NewPosition).Length());
LOGD("Too far away (%0.2f), \"repairing\" the client", (OldPosition - a_Pos).Length());
SendPlayerMoveLook();
return;
}
if (cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*m_Player, OldPosition, NewPosition, PreviousIsOnGround))
if (cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*m_Player, OldPosition, a_Pos, PreviousIsOnGround))
{
SendPlayerMoveLook();
return;
@ -1657,18 +1650,18 @@ void cClientHandle::HandlePlayerMove(double a_PosX, double a_PosY, double a_PosZ
// TODO: should do some checks to see if player is not moving through terrain
// TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too
m_Player->SetPosition(NewPosition);
m_Player->SetPosition(a_Pos);
m_Player->SetTouchGround(a_IsOnGround);
m_Player->UpdateMovementStats(NewPosition - OldPosition, PreviousIsOnGround);
m_Player->UpdateMovementStats(a_Pos - OldPosition, PreviousIsOnGround);
}
void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, float a_Rotation, float a_Pitch, bool a_IsOnGround)
void cClientHandle::HandlePlayerMoveLook(Vector3d a_Pos, float a_Rotation, float a_Pitch, bool a_IsOnGround)
{
HandlePlayerMove(a_PosX, a_PosY, a_PosZ, a_IsOnGround);
HandlePlayerMove(a_Pos, a_IsOnGround);
HandlePlayerLook(a_Rotation, a_Pitch, a_IsOnGround);
}
@ -1768,7 +1761,7 @@ void cClientHandle::HandleUpdateSign(
const AString & a_Line3, const AString & a_Line4
)
{
if (m_LastPlacedSign.Equals(Vector3i(a_BlockPos)))
if (m_LastPlacedSign.Equals(a_BlockPos))
{
m_LastPlacedSign.Set(0, -1, 0);
m_Player->GetWorld()->SetSignLines(a_BlockPos, a_Line1, a_Line2, a_Line3, a_Line4, m_Player);
@ -1865,7 +1858,10 @@ void cClientHandle::HandleUseItem(bool a_UsedMainHand)
LOGD("HandleUseItem: Hand: %d; HeldItem: %s", a_UsedMainHand, ItemToFullString(HeldItem).c_str());
if (PlgMgr->CallHookPlayerRightClick(*m_Player, {-1, 255, -1}, BLOCK_FACE_NONE, {0, 0, 0}))
constexpr Vector3i DefaultBlockPos(-1, 255, -1);
constexpr Vector3i DefaultCursorPos(0, 0, 0);
if (PlgMgr->CallHookPlayerRightClick(*m_Player, DefaultBlockPos, BLOCK_FACE_NONE, DefaultCursorPos))
{
return; // Plugin denied click action
}
@ -1897,12 +1893,12 @@ void cClientHandle::HandleUseItem(bool a_UsedMainHand)
else
{
// Use an item in hand without a target block
if (!PlgMgr->CallHookPlayerUsingItem(*m_Player, {-1, 255, -1}, BLOCK_FACE_NONE, {0, 0, 0}))
if (!PlgMgr->CallHookPlayerUsingItem(*m_Player, DefaultBlockPos, BLOCK_FACE_NONE, DefaultCursorPos))
{
// All plugins agree with using the item
cBlockInServerPluginInterface PluginInterface(*World);
ItemHandler.OnItemUse(World, m_Player, PluginInterface, HeldItem, {-1, 255, -1}, BLOCK_FACE_NONE);
PlgMgr->CallHookPlayerUsedItem(*m_Player, {-1, 255, -1}, BLOCK_FACE_NONE, {0, 0, 0});
ItemHandler.OnItemUse(World, m_Player, PluginInterface, HeldItem, DefaultBlockPos, BLOCK_FACE_NONE);
PlgMgr->CallHookPlayerUsedItem(*m_Player, DefaultBlockPos, BLOCK_FACE_NONE, DefaultCursorPos);
}
}
}
@ -2687,13 +2683,13 @@ void cClientHandle::SendExplosion(const Vector3f a_Position, const float a_Power
auto ParticleCount = std::min(static_cast<int>(ParticleFormula * 125), 600);
// Dark smoke particles:
SendParticleEffect("largesmoke", a_Position, Vector3f(), Spread, static_cast<int>(ParticleCount));
SendParticleEffect("largesmoke", a_Position, {0.f, 0.f, 0.f,}, Spread, static_cast<int>(ParticleCount));
Spread = ParticleFormula * 0.35f;
ParticleCount = std::min(static_cast<int>(ParticleFormula * 550), 1800);
// Light smoke particles:
SendParticleEffect("explode", a_Position, Vector3f(), Spread, static_cast<int>(ParticleCount));
SendParticleEffect("explode", a_Position, {0.f, 0.f, 0.f,}, Spread, static_cast<int>(ParticleCount));
// Shockwave effect:
m_Protocol->SendExplosion(a_Position, a_Power);

View File

@ -370,14 +370,14 @@ public: // tolua_export
/** Verifies and sets player position, performing relevant checks.
Calls relevant methods to process movement related statistics.
Requires state of previous position and on-ground status, so must be called when these are still intact. */
void HandlePlayerMove(double a_PosX, double a_PosY, double a_PosZ, bool a_IsOnGround);
void HandlePlayerMove(Vector3d a_Pos, bool a_IsOnGround);
void HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, float a_Rotation, float a_Pitch, bool a_IsOnGround);
void HandlePlayerMoveLook(Vector3d a_Pos, float a_Rotation, float a_Pitch, bool a_IsOnGround);
void HandlePluginMessage (const AString & a_Channel, ContiguousByteBufferView a_Message);
void HandleRespawn (void);
void HandleRightClick (Vector3i a_BlockPos, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, bool a_UsedMainHand);
void HandleRightClick (Vector3i a_BlockPos, eBlockFace a_BlockFace, Vector3i a_Cursor, bool a_UsedMainHand);
void HandleSlotSelected (Int16 a_SlotNum);
void HandleSpectate (const cUUID & a_PlayerUUID);
@ -540,6 +540,8 @@ private:
static int s_ClientCount;
static Vector3i s_IllegalPosition;
/** ID used for identification during authenticating. Assigned sequentially for each new instance. */
int m_UniqueID;

View File

@ -95,7 +95,7 @@ void cEnderCrystal::KilledBy(TakeDamageInfo & a_TDI)
m_World->DoExplosionAt(6.0, GetPosX(), GetPosY() + GetHeight() / 2, GetPosZ(), true, esEnderCrystal, this);
const auto Position = GetPosition().Floor();
if (cChunkDef::IsValidHeight(Position.y))
if (cChunkDef::IsValidHeight(Position))
{
m_World->SetBlock(Position, E_BLOCK_FIRE, 0);
}

View File

@ -1131,7 +1131,7 @@ void cEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
// Get water direction
Vector3f WaterDir = m_World->GetWaterSimulator()->GetFlowingDirection(BlockX, BlockY, BlockZ);
Vector3f WaterDir = m_World->GetWaterSimulator()->GetFlowingDirection({BlockX, BlockY, BlockZ});
m_WaterSpeed *= 0.9; // Reduce speed each tick
@ -1433,7 +1433,7 @@ bool cEntity::DetectPortal()
return false;
}
if (const auto Position = m_Position.Floor(); cChunkDef::IsValidHeight(Position.y))
if (const auto Position = m_Position.Floor(); cChunkDef::IsValidHeight(Position))
{
switch (GetWorld()->GetBlock(Position))
{

View File

@ -320,7 +320,7 @@ void cPawn::HandleFalling(void)
With this in mind, we first check the block at the player's feet, then the one below that (because fences),
and decide which behaviour we want to go with.
*/
BLOCKTYPE BlockAtFoot = (cChunkDef::IsValidHeight(POSY_TOINT)) ? GetWorld()->GetBlock(POS_TOINT) : static_cast<BLOCKTYPE>(E_BLOCK_AIR);
BLOCKTYPE BlockAtFoot = (cChunkDef::IsValidHeight(POS_TOINT)) ? GetWorld()->GetBlock(POS_TOINT) : static_cast<BLOCKTYPE>(E_BLOCK_AIR);
/* We initialize these with what the foot is really IN, because for sampling we will move down with the epsilon above */
bool IsFootInWater = IsBlockWater(BlockAtFoot);
@ -364,7 +364,7 @@ void cPawn::HandleFalling(void)
{
Vector3i BlockTestPosition = CrossTestPosition.Floor() + BlockSampleOffsets[j];
if (!cChunkDef::IsValidHeight(BlockTestPosition.y))
if (!cChunkDef::IsValidHeight(BlockTestPosition))
{
continue;
}

View File

@ -2192,7 +2192,7 @@ bool cPlayer::IsClimbing(void) const
{
const auto Position = GetPosition().Floor();
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
return false;
}
@ -2579,7 +2579,7 @@ bool cPlayer::IsInsideWater()
{
const auto EyePos = GetEyePosition().Floor();
if (!cChunkDef::IsValidHeight(EyePos.y))
if (!cChunkDef::IsValidHeight(EyePos))
{
// Not in water if in void.
return false;

View File

@ -555,7 +555,7 @@ void cFinishGenTallGrass::GenFinish(cChunkDesc & a_ChunkDesc)
)
{
y--;
if (!cChunkDef::IsValidHeight(y - 1))
if (!cChunkDef::IsValidHeight({x, y - 1, z}))
{
failed = true;
break;
@ -1986,7 +1986,7 @@ void cFinishGenOreNests::GenerateOre(
for (int y = ysize; y >= 0; --y)
{
int BlockY = BaseY + y;
if (!cChunkDef::IsValidHeight(BlockY))
if (!cChunkDef::IsValidHeight({BlockX, BlockY, BaseZ}))
{
Num++; // So that the cycle finishes even if the base coords wander away from the chunk
continue;

View File

@ -70,7 +70,7 @@ public:
// Block above must be air to spawn a boat (prevents spawning a boat underwater)
auto PosAbove = Callbacks.m_Pos.Floor().addedY(1);
if (!cChunkDef::IsValidHeight(PosAbove.y))
if (!cChunkDef::IsValidHeight(PosAbove))
{
return false;
}

View File

@ -365,7 +365,7 @@ public:
)
{
if (
!cChunkDef::IsValidHeight(Position.y) ||
!cChunkDef::IsValidHeight(Position) ||
(a_World.GetBlock(Position) != E_BLOCK_GRASS) // Are we looking at grass?
)
{

View File

@ -1063,7 +1063,7 @@ void cItemHandler::OnPlayerPlace(cPlayer & a_Player, const cItem & a_HeldItem, c
NIBBLETYPE PlaceMeta;
const auto PlacePosition = AddFaceDirection(a_ClickedPosition, a_ClickedBlockFace);
if (!cChunkDef::IsValidHeight(PlacePosition.y) || !World.GetBlockTypeMeta(PlacePosition, PlaceBlock, PlaceMeta))
if (!cChunkDef::IsValidHeight(PlacePosition) || !World.GetBlockTypeMeta(PlacePosition, PlaceBlock, PlaceMeta))
{
// The block is being placed outside the world, ignore this packet altogether (GH #128):
return;

View File

@ -57,7 +57,7 @@ public:
}
const auto FirePos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace);
if (!cChunkDef::IsValidHeight(FirePos.y))
if (!cChunkDef::IsValidHeight(FirePos))
{
return false;
}

View File

@ -79,7 +79,7 @@ bool cMobSpawner::CanSpawnHere(cChunk * a_Chunk, Vector3i a_RelPos, eMonsterType
return false;
}
if (cChunkDef::IsValidHeight(a_RelPos.y - 1) && (a_Chunk->GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_BEDROCK))
if (cChunkDef::IsValidHeight(a_RelPos.addedY(-1)) && (a_Chunk->GetBlock(a_RelPos.addedY(-1)) == E_BLOCK_BEDROCK))
{
return false; // Make sure mobs do not spawn on bedrock.
}

View File

@ -480,7 +480,7 @@ void cPath::FillCellAttributes(cPathCell & a_Cell)
ASSERT(m_Chunk != nullptr);
if (!cChunkDef::IsValidHeight(Location.y))
if (!cChunkDef::IsValidHeight(Location))
{
// Players can't build outside the game height, so it must be air
a_Cell.m_IsSolid = false;

View File

@ -185,74 +185,78 @@ bool cPathFinder::EnsureProperPoint(Vector3d & a_Vector, cChunk & a_Chunk)
return false;
}
int RelX = FloorC(a_Vector.x) - Chunk->GetPosX() * cChunkDef::Width;
int RelZ = FloorC(a_Vector.z) - Chunk->GetPosZ() * cChunkDef::Width;
// If destination in the air, first try to go 1 block north, or east, or west.
// This fixes the player leaning issue.
// If that failed, we instead go down to the lowest air block.
int YBelowUs = FloorC(a_Vector.y) - 1;
if (!cChunkDef::IsValidHeight(YBelowUs))
auto Below = a_Vector.Floor().addedY(-1);
if (!cChunkDef::IsValidHeight(Below))
{
return false;
}
Chunk->GetBlockTypeMeta(RelX, YBelowUs, RelZ, BlockType, BlockMeta);
auto BelowRel = cChunkDef::AbsoluteToRelative(Below);
Chunk->GetBlockTypeMeta(BelowRel, BlockType, BlockMeta);
if (!(IsWaterOrSolid(BlockType)))
{
bool InTheAir = true;
int x, z;
for (z = -1; z <= 1; ++z)
constexpr std::array<Vector3i, 8> Offsets =
{
for (x = -1; x <= 1; ++x)
{
if ((x == 0) && (z == 0))
{
continue;
}
Chunk = a_Chunk.GetNeighborChunk(FloorC(a_Vector.x+x), FloorC(a_Vector.z+z));
if ((Chunk == nullptr) || !Chunk->IsValid())
{
return false;
}
RelX = FloorC(a_Vector.x+x) - Chunk->GetPosX() * cChunkDef::Width;
RelZ = FloorC(a_Vector.z+z) - Chunk->GetPosZ() * cChunkDef::Width;
Chunk->GetBlockTypeMeta(RelX, YBelowUs, RelZ, BlockType, BlockMeta);
if (IsWaterOrSolid((BlockType)))
{
a_Vector.x += x;
a_Vector.z += z;
InTheAir = false;
goto breakBothLoops;
}
{-1, 0, 0},
{1, 0, 0},
{0, 0, -1},
{0, 0, 1},
{-1, 0, -1},
{-1, 0, 1},
{1, 0, -1},
{1, 0, 1},
}
};
// Looks for a neighbouring block one block in x or z direction that is water or solid.
bool InTheAir = true;
for (const auto & Offset : Offsets)
{
auto InspectPos = Below + Offset;
Chunk = a_Chunk.GetNeighborChunk(InspectPos.x, InspectPos.z);
if ((Chunk == nullptr) || !Chunk->IsValid())
{
return false;
}
auto InspectRel = cChunkDef::AbsoluteToRelative(InspectPos);
Chunk->GetBlockTypeMeta(InspectRel, BlockType, BlockMeta);
if (IsWaterOrSolid((BlockType)))
{
BelowRel = InspectRel;
InTheAir = false;
break;
}
}
breakBothLoops:
// Go down to the lowest air block.
if (InTheAir)
{
while (a_Vector.y > 0)
while (cChunkDef::IsValidHeight(a_Vector.addedY(-1)))
{
Chunk->GetBlockTypeMeta(RelX, FloorC(a_Vector.y) - 1, RelZ, BlockType, BlockMeta);
Chunk->GetBlockTypeMeta(BelowRel.addedY(-1), BlockType, BlockMeta);
if (IsWaterOrSolid(BlockType))
{
break;
}
a_Vector.y -= 1;
BelowRel.y -= 1;
}
}
}
// If destination in water or solid, go up to the first air block.
while (a_Vector.y < cChunkDef::Height)
while (BelowRel.y < cChunkDef::Height)
{
Chunk->GetBlockTypeMeta(RelX, FloorC(a_Vector.y), RelZ, BlockType, BlockMeta);
Chunk->GetBlockTypeMeta(BelowRel, BlockType, BlockMeta);
if (!IsWaterOrSolid(BlockType))
{
break;
}
a_Vector.y += 1;
BelowRel.y += 1;
}
return true;

View File

@ -342,7 +342,7 @@ namespace Explodinator
while (a_Intensity > 0)
{
auto Position = Checkpoint.Floor();
if (!cChunkDef::IsValidHeight(Position.y))
if (!cChunkDef::IsValidHeight(Position))
{
break;
}

View File

@ -600,7 +600,7 @@ void cProtocol_1_11_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorY);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorZ);
m_Client->HandleRightClick(Position, FaceIntToBlockFace(Face), FloorC(CursorX * 16), FloorC(CursorY * 16), FloorC(CursorZ * 16), Hand == 0);
m_Client->HandleRightClick(Position, FaceIntToBlockFace(Face), {FloorC(CursorX * 16), FloorC(CursorY * 16), FloorC(CursorZ * 16)}, Hand == 0);
}

View File

@ -2381,7 +2381,7 @@ void cProtocol_1_8_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
}
else
{
m_Client->HandleRightClick(BlockPos, blockFace, CursorX, CursorY, CursorZ, true);
m_Client->HandleRightClick(BlockPos, blockFace, {CursorX, CursorY, CursorZ}, true);
}
}
@ -2553,7 +2553,7 @@ void cProtocol_1_8_0::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
m_Client->HandlePlayerMove(PosX, PosY, PosZ, IsOnGround);
m_Client->HandlePlayerMove({PosX, PosY, PosZ}, IsOnGround);
}
@ -2569,7 +2569,7 @@ void cProtocol_1_8_0::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Yaw, Pitch, IsOnGround);
m_Client->HandlePlayerMoveLook({PosX, PosY, PosZ}, Yaw, Pitch, IsOnGround);
}

View File

@ -901,7 +901,7 @@ void cProtocol_1_9_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorY);
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorZ);
m_Client->HandleRightClick(Position, FaceIntToBlockFace(Face), CursorX, CursorY, CursorZ, Hand == MAIN_HAND);
m_Client->HandleRightClick(Position, FaceIntToBlockFace(Face), {CursorX, CursorY, CursorZ}, Hand == MAIN_HAND);
}
@ -1003,7 +1003,7 @@ void cProtocol_1_9_0::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
if (m_IsTeleportIdConfirmed)
{
m_Client->HandlePlayerMove(PosX, PosY, PosZ, IsOnGround);
m_Client->HandlePlayerMove({PosX, PosY, PosZ}, IsOnGround);
}
}
@ -1022,7 +1022,7 @@ void cProtocol_1_9_0::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
if (m_IsTeleportIdConfirmed)
{
m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Yaw, Pitch, IsOnGround);
m_Client->HandlePlayerMoveLook({PosX, PosY, PosZ}, Yaw, Pitch, IsOnGround);
}
}

View File

@ -145,7 +145,7 @@ void cDelayedFluidSimulator::AddBlock(cChunk & a_Chunk, Vector3i a_Position, BLO
void cDelayedFluidSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position, BLOCKTYPE a_Block)
{
if (!cChunkDef::IsValidHeight(a_Position.y))
if (!cChunkDef::IsValidHeight(a_Position))
{
// Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1)
return;

View File

@ -130,14 +130,14 @@ bool cFluidSimulator::IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2)
Vector3f cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z)
Vector3f cFluidSimulator::GetFlowingDirection(Vector3i a_Pos)
{
if (!cChunkDef::IsValidHeight(a_Y))
if (!cChunkDef::IsValidHeight(a_Pos))
{
return {};
}
if (!IsAllowedBlock(m_World.GetBlock({ a_X, a_Y, a_Z }))) // No Fluid -> No Flowing direction :D
if (!IsAllowedBlock(m_World.GetBlock(a_Pos))) // No Fluid -> No Flowing direction :D
{
return {};
}
@ -148,24 +148,24 @@ Vector3f cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z)
return ((a_BlockMeta & 0x08) != 0) ? 0 : a_BlockMeta;
};
auto BlockMeta = m_World.GetBlockMeta({ a_X, a_Y, a_Z });
auto BlockMeta = m_World.GetBlockMeta(a_Pos);
NIBBLETYPE CentralPoint = HeightFromMeta(BlockMeta);
NIBBLETYPE LevelPoint[4];
// blocks around the checking pos
Vector3i Points[]
std::array<Vector3i, 4> Offsets {
{
{ a_X + 1, a_Y, a_Z },
{ a_X, a_Y, a_Z + 1 },
{ a_X - 1, a_Y, a_Z },
{ a_X, a_Y, a_Z - 1 }
};
{ 1, 0, 0 },
{ 0, 0, 1 },
{ 1, 0, 0 },
{ 0, 0, 1 }
}};
for (size_t i = 0; i < ARRAYCOUNT(LevelPoint); i++)
for (size_t i = 0; i < Offsets.size(); i++)
{
if (IsAllowedBlock(m_World.GetBlock(Points[i])))
if (IsAllowedBlock(m_World.GetBlock(a_Pos + Offsets[i])))
{
LevelPoint[i] = HeightFromMeta(m_World.GetBlockMeta(Points[i]));
LevelPoint[i] = HeightFromMeta(m_World.GetBlockMeta(Offsets[i]));
}
else
{

View File

@ -44,7 +44,7 @@ public:
cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid);
/** Returns a unit vector in the direction the fluid is flowing or a zero-vector if not flowing. */
virtual Vector3f GetFlowingDirection(int a_X, int a_Y, int a_Z);
virtual Vector3f GetFlowingDirection(Vector3i a_Pos);
/** Creates a ChunkData object for the simulator to use. The simulator returns the correct object type. */
virtual cFluidSimulatorData * CreateChunkData(void) = 0;

View File

@ -26,7 +26,7 @@ ForEachSourceCallback::ForEachSourceCallback(const cChunk & Chunk, const Vector3
void ForEachSourceCallback::operator()(Vector3i Location)
{
if (!cChunkDef::IsValidHeight(Location.y))
if (!cChunkDef::IsValidHeight(Location))
{
return;
}
@ -96,7 +96,7 @@ PowerLevel ForEachSourceCallback::QueryLinkedPower(const cChunk & Chunk, const V
for (const auto & Offset : cSimulator::GetLinkedOffsets(SolidBlockPosition - QueryPosition))
{
auto SourcePosition = QueryPosition + Offset;
if (!cChunkDef::IsValidHeight(SourcePosition.y))
if (!cChunkDef::IsValidHeight(SourcePosition))
{
continue;
}

View File

@ -217,7 +217,7 @@ void cIncrementalRedstoneSimulator::WakeUp(cChunk & a_Chunk, Vector3i a_Position
for (const auto & Offset : cSimulator::GetLinkedOffsets(a_Offset))
{
auto Relative = a_Position - a_Offset + Offset;
if (!cChunkDef::IsValidHeight(Relative.y))
if (!cChunkDef::IsValidHeight(Relative))
{
continue;
}

View File

@ -313,7 +313,7 @@ namespace RedstoneWireHandler
const auto YMDiagonalPosition = Relative + OffsetYM;
if (
BLOCKTYPE QueryBlock;
cChunkDef::IsValidHeight(YMDiagonalPosition.y) &&
cChunkDef::IsValidHeight(YMDiagonalPosition) &&
a_Chunk.UnboundedRelGetBlockType(YMDiagonalPosition, QueryBlock) &&
(QueryBlock == E_BLOCK_REDSTONE_WIRE)
)

View File

@ -71,7 +71,7 @@ void cSimulatorManager::WakeUp(cChunk & a_Chunk, Vector3i a_Position)
for (const auto & Offset : cSimulator::AdjacentOffsets)
{
auto Relative = a_Position + Offset;
if (!cChunkDef::IsValidHeight(Relative.y))
if (!cChunkDef::IsValidHeight(Relative))
{
continue;
}

View File

@ -850,42 +850,37 @@ bool cWorld::CanSpawnAt(int a_X, int & a_Y, int a_Z)
bool cWorld::CheckPlayerSpawnPoint(int a_PosX, int a_PosY, int a_PosZ)
bool cWorld::CheckPlayerSpawnPoint(Vector3i a_Pos)
{
// Check height bounds
if (!cChunkDef::IsValidHeight(a_PosY))
if (!cChunkDef::IsValidHeight(a_Pos))
{
return false;
}
// Check that surrounding blocks are neither solid or liquid
static const Vector3i SurroundingCoords[] =
constexpr std::array<Vector3i, 8> SurroundingCoords =
{{
{0, 0, 1},
{1, 0, 1},
{1, 0, 0},
{1, 0, -1},
{0, 0, -1},
{-1, 0, -1},
{-1, 0, 0},
{-1, 0, 1},
}};
for (const auto & Offset : SurroundingCoords)
{
Vector3i(0, 0, 1),
Vector3i(1, 0, 1),
Vector3i(1, 0, 0),
Vector3i(1, 0, -1),
Vector3i(0, 0, -1),
Vector3i(-1, 0, -1),
Vector3i(-1, 0, 0),
Vector3i(-1, 0, 1),
};
static const int SurroundingCoordsCount = ARRAYCOUNT(SurroundingCoords);
for (int CoordIndex = 0; CoordIndex < SurroundingCoordsCount; ++CoordIndex)
{
const int XPos = a_PosX + SurroundingCoords[CoordIndex].x;
const int ZPos = a_PosZ + SurroundingCoords[CoordIndex].z;
const BLOCKTYPE BlockType = GetBlock({ XPos, a_PosY, ZPos });
const BLOCKTYPE BlockType = GetBlock(a_Pos + Offset);
if (cBlockInfo::IsSolid(BlockType) || IsBlockLiquid(BlockType))
{
return false;
return true;
}
}
return true;
return false;
}

View File

@ -311,12 +311,7 @@ public:
void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ);
/** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. */
bool SetSignLines(Vector3i a_BlockPos, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr);
bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr) // Exported in ManualBindings.cpp
{
return SetSignLines({a_BlockX, a_BlockY, a_BlockZ}, a_Line1, a_Line2, a_Line3, a_Line4, a_Player);
}
bool SetSignLines(Vector3i a_BlockPos, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp
/** Sets the command block command. Returns true if command changed. */
bool SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command); // tolua_export
@ -1137,7 +1132,11 @@ private:
bool CanSpawnAt(int a_X, int & a_Y, int a_Z);
/** Check if player starting point is acceptable */
bool CheckPlayerSpawnPoint(int a_PosX, int a_PosY, int a_PosZ);
bool CheckPlayerSpawnPoint(int a_PosX, int a_PosY, int a_PosZ)
{
return CheckPlayerSpawnPoint({a_PosX, a_PosY, a_PosZ});
}
bool CheckPlayerSpawnPoint(Vector3i a_Pos);
/** Chooses a reasonable transition from the current weather to a new weather */
eWeather ChooseNewWeather(void);