Fix lilypad displacing block above (#5056)
* Fix lilypad displacing block above Side fixes: * Fix lilypad displacing half slabs * Fix lilypad being placed on flowing water and non-water blocks in general Co-authored-by: Tiger Wang <ziwei.tiger@outlook.com>
This commit is contained in:
parent
280f7a81f4
commit
7027b2279f
@ -44,10 +44,35 @@ public:
|
|||||||
eBlockFace a_ClickedBlockFace
|
eBlockFace a_ClickedBlockFace
|
||||||
) override
|
) override
|
||||||
{
|
{
|
||||||
if (a_ClickedBlockFace > BLOCK_FACE_NONE)
|
// The client sends BLOCK_FACE_NONE when it determines it should do a tracing-based placement.
|
||||||
|
// Otherwise, a normal block face is sent.
|
||||||
|
|
||||||
|
if (a_ClickedBlockFace != BLOCK_FACE_NONE)
|
||||||
{
|
{
|
||||||
// Clicked on a face of a submerged block; vanilla allows placement, so should we
|
// The position the client wants the lilypad placed.
|
||||||
auto PlacePos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace);
|
const auto PlacePos = AddFaceDirection(a_ClickedBlockPos, a_ClickedBlockFace);
|
||||||
|
|
||||||
|
// Lilypad should not replace non air and non water blocks:
|
||||||
|
if (
|
||||||
|
const auto BlockToReplace = a_World->GetBlock(PlacePos);
|
||||||
|
(BlockToReplace != E_BLOCK_AIR) &&
|
||||||
|
(BlockToReplace != E_BLOCK_WATER) &&
|
||||||
|
(BlockToReplace != E_BLOCK_STATIONARY_WATER)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lilypad should be placed only if there is a water block below
|
||||||
|
if (
|
||||||
|
const auto BlockBelow = a_World->GetBlock(PlacePos.addedY(-1));
|
||||||
|
(BlockBelow != E_BLOCK_WATER) &&
|
||||||
|
(BlockBelow != E_BLOCK_STATIONARY_WATER)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
a_World->SetBlock(PlacePos, E_BLOCK_LILY_PAD, 0);
|
a_World->SetBlock(PlacePos, E_BLOCK_LILY_PAD, 0);
|
||||||
if (!a_Player->IsGameModeCreative())
|
if (!a_Player->IsGameModeCreative())
|
||||||
{
|
{
|
||||||
@ -61,53 +86,50 @@ public:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
cCallbacks():
|
|
||||||
m_HasHitFluid(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool OnNextBlock(Vector3i a_CBBlockPos, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, eBlockFace a_CBEntryFace) override
|
virtual bool OnNextBlock(Vector3i a_CBBlockPos, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, eBlockFace a_CBEntryFace) override
|
||||||
{
|
{
|
||||||
if (IsBlockWater(a_CBBlockType))
|
if (
|
||||||
|
!IsBlockWater(a_CBBlockType) ||
|
||||||
|
(a_CBBlockMeta != 0) // The hit block should be a source
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if ((a_CBBlockMeta != 0) || (a_CBEntryFace == BLOCK_FACE_NONE)) // The hit block should be a source. The FACE_NONE check is clicking whilst submerged
|
// TODO: Vanilla stops the trace. However, we need to continue the trace, to work around our lack of block bounding box support
|
||||||
{
|
// which would otherwise mean we misbehave when clicking through the voxel a (e.g.) button occupies. Now, however, we misbehave
|
||||||
return false;
|
// when clicking on a block near water... Nonetheless, the former would cause ghost blocks, so continue for now.
|
||||||
}
|
|
||||||
a_CBBlockPos = AddFaceDirection(a_CBBlockPos, BLOCK_FACE_YP); // Always place pad at top of water block
|
// Ignore and continue trace:
|
||||||
if (
|
return false;
|
||||||
!IsBlockWater(a_CBBlockType) &&
|
|
||||||
cBlockInfo::FullyOccupiesVoxel(a_CBBlockType)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Can't place lilypad on air / in another block!
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
m_HasHitFluid = true;
|
|
||||||
m_Pos = a_CBBlockPos;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
Position = AddFaceDirection(a_CBBlockPos, BLOCK_FACE_YP); // Always place pad at top of water block
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3i m_Pos;
|
Vector3i Position;
|
||||||
bool m_HasHitFluid;
|
|
||||||
|
|
||||||
} Callbacks;
|
} Callbacks;
|
||||||
auto Start = a_Player->GetEyePosition() + a_Player->GetLookVector();
|
|
||||||
auto End = a_Player->GetEyePosition() + a_Player->GetLookVector() * 5;
|
|
||||||
cLineBlockTracer::Trace(*a_Player->GetWorld(), Callbacks, Start, End);
|
|
||||||
|
|
||||||
if (Callbacks.m_HasHitFluid)
|
const auto EyePosition = a_Player->GetEyePosition();
|
||||||
|
const auto End = EyePosition + a_Player->GetLookVector() * 5;
|
||||||
|
if (cLineBlockTracer::Trace(*a_Player->GetWorld(), Callbacks, EyePosition, End))
|
||||||
{
|
{
|
||||||
a_World->SetBlock(Callbacks.m_Pos, E_BLOCK_LILY_PAD, 0);
|
// The line traced to completion; no suitable water was found:
|
||||||
if (!a_Player->IsGameModeCreative())
|
return false;
|
||||||
{
|
|
||||||
a_Player->GetInventory().RemoveOneEquippedItem();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
const auto BlockToReplace = a_World->GetBlock(Callbacks.Position);
|
||||||
|
if (BlockToReplace != E_BLOCK_AIR)
|
||||||
|
{
|
||||||
|
// Lilypad should not replace non air blocks:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_World->SetBlock(Callbacks.Position, E_BLOCK_LILY_PAD, 0);
|
||||||
|
if (!a_Player->IsGameModeCreative())
|
||||||
|
{
|
||||||
|
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user