diff options
author | Mattes D <github@xoft.cz> | 2020-04-21 22:19:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-21 22:19:22 +0200 |
commit | 487f9a2aa9b5497495cef1ac3b9c7a603e69f862 (patch) | |
tree | 054a846942f414060e29c72f4a717c8a89e70893 /src/Blocks/BlockBed.cpp | |
parent | Delet SpawnObject params (diff) | |
download | cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.gz cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.bz2 cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.lz cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.xz cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.tar.zst cuberite-487f9a2aa9b5497495cef1ac3b9c7a603e69f862.zip |
Diffstat (limited to 'src/Blocks/BlockBed.cpp')
-rw-r--r-- | src/Blocks/BlockBed.cpp | 150 |
1 files changed, 82 insertions, 68 deletions
diff --git a/src/Blocks/BlockBed.cpp b/src/Blocks/BlockBed.cpp index 8b349ef5e..6d50e8c41 100644 --- a/src/Blocks/BlockBed.cpp +++ b/src/Blocks/BlockBed.cpp @@ -15,7 +15,11 @@ -void cBlockBedHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, Vector3i a_BlockPos, BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta) +void cBlockBedHandler::OnBroken( + cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, + const Vector3i a_BlockPos, + BLOCKTYPE a_OldBlockType, NIBBLETYPE a_OldBlockMeta +) { auto Direction = MetaDataToDirection(a_OldBlockMeta & 0x03); if ((a_OldBlockMeta & 0x08) != 0) @@ -50,87 +54,97 @@ void cBlockBedHandler::OnBroken(cChunkInterface & a_ChunkInterface, cWorldInterf -bool cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) +bool cBlockBedHandler::OnUse( + cChunkInterface & a_ChunkInterface, + cWorldInterface & a_WorldInterface, + cPlayer & a_Player, + const Vector3i a_BlockPos, + eBlockFace a_BlockFace, + const Vector3i a_CursorPos +) { - Vector3i Coords(a_BlockX, a_BlockY, a_BlockZ); + // Sleeping in bed only allowed in Overworld, beds explode elsewhere: if (a_WorldInterface.GetDimension() != dimOverworld) { - a_WorldInterface.DoExplosionAt(5, a_BlockX, a_BlockY, a_BlockZ, true, esBed, &Coords); + auto PosCopy = a_BlockPos; + a_WorldInterface.DoExplosionAt(5, a_BlockPos.x, a_BlockPos.y, a_BlockPos.z, true, esBed, &PosCopy); + return true; } - else if (!((a_WorldInterface.GetTimeOfDay() > 12541) && (a_WorldInterface.GetTimeOfDay() < 23458))) // Source: https://minecraft.gamepedia.com/Bed#Sleeping + + // Sleeping is allowed only during night: + // TODO: Also during thunderstorms + if (!((a_WorldInterface.GetTimeOfDay() > 12541) && (a_WorldInterface.GetTimeOfDay() < 23458))) // Source: https://minecraft.gamepedia.com/Bed#Sleeping { a_Player.SendMessageFailure("You can only sleep at night"); + return true; + } + + // Check if the bed is occupied: + auto Meta = a_ChunkInterface.GetBlockMeta(a_BlockPos); + if ((Meta & 0x04) == 0x04) + { + a_Player.SendMessageFailure("This bed is occupied"); + return true; + } + + // Cannot sleep if there are hostile mobs nearby: + auto FindMobs = [](cEntity & a_Entity) + { + return ( + (a_Entity.GetEntityType() == cEntity::etMonster) && + (static_cast<cMonster&>(a_Entity).GetMobFamily() == cMonster::mfHostile) + ); + }; + if (!a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(a_Player.GetPosition() - Vector3i(0, 5, 0), 8, 10), FindMobs)) + { + a_Player.SendMessageFailure("You may not rest now, there are monsters nearby"); + return true; + } + + // Broadcast the "Use bed" for the pillow block: + if ((Meta & 0x8) == 0x8) + { + // Is pillow + a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, a_BlockPos); } else { - NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(Coords); - if ((Meta & 0x4) == 0x4) + // Is foot end + VERIFY((Meta & 0x04) != 0x04); // Occupied flag should never be set, else our compilator (intended) is broken + + auto PillowPos = a_BlockPos + MetaDataToDirection(Meta & 0x03); + if (a_ChunkInterface.GetBlock(PillowPos) == E_BLOCK_BED) // Must always use pillow location for sleeping { - a_Player.SendMessageFailure("This bed is occupied"); + a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, PillowPos); } - else - { - auto FindMobs = [](cEntity & a_Entity) - { - return ( - (a_Entity.GetEntityType() == cEntity::etMonster) && - (static_cast<cMonster&>(a_Entity).GetMobFamily() == cMonster::mfHostile) - ); - }; + } - if (!a_Player.GetWorld()->ForEachEntityInBox(cBoundingBox(a_Player.GetPosition() - Vector3i(0, 5, 0), 8, 10), FindMobs)) - { - a_Player.SendMessageFailure("You may not rest now, there are monsters nearby"); - } - else + // Occupy the bed: + a_Player.SetBedPos(a_BlockPos); + SetBedOccupationState(a_ChunkInterface, a_Player.GetLastBedPos(), true); + a_Player.SetIsInBed(true); + a_Player.SendMessageSuccess("Home position set successfully"); + + // Fast-forward the time if all players in the world are in their beds: + auto TimeFastForwardTester = [](cPlayer & a_OtherPlayer) + { + if (!a_OtherPlayer.IsInBed()) + { + return true; + } + return false; + }; + if (a_WorldInterface.ForEachPlayer(TimeFastForwardTester)) + { + a_WorldInterface.ForEachPlayer([&](cPlayer & a_OtherPlayer) { - Vector3i PillowDirection(0, 0, 0); - - if ((Meta & 0x8) == 0x8) - { - // Is pillow - a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, { a_BlockX, a_BlockY, a_BlockZ }); - } - else - { - // Is foot end - VERIFY((Meta & 0x4) != 0x4); // Occupied flag should never be set, else our compilator (intended) is broken - - PillowDirection = MetaDataToDirection(Meta & 0x3); - if (a_ChunkInterface.GetBlock(Coords + PillowDirection) == E_BLOCK_BED) // Must always use pillow location for sleeping - { - a_WorldInterface.GetBroadcastManager().BroadcastUseBed(a_Player, Vector3i{a_BlockX, a_BlockY, a_BlockZ} + PillowDirection); - } - } - - a_Player.SetBedPos(Coords); - SetBedOccupationState(a_ChunkInterface, a_Player.GetLastBedPos(), true); - a_Player.SetIsInBed(true); - a_Player.SendMessageSuccess("Home position set successfully"); - - auto TimeFastForwardTester = [](cPlayer & a_OtherPlayer) - { - if (!a_OtherPlayer.IsInBed()) - { - return true; - } - return false; - }; - - if (a_WorldInterface.ForEachPlayer(TimeFastForwardTester)) - { - a_WorldInterface.ForEachPlayer([&](cPlayer & a_OtherPlayer) - { - cBlockBedHandler::SetBedOccupationState(a_ChunkInterface, a_OtherPlayer.GetLastBedPos(), false); - a_OtherPlayer.SetIsInBed(false); - return false; - } - ); - a_WorldInterface.SetTimeOfDay(0); - a_ChunkInterface.SetBlockMeta({a_BlockX, a_BlockY, a_BlockZ}, Meta & 0x0b); // Clear the "occupied" bit of the bed's block - } + cBlockBedHandler::SetBedOccupationState(a_ChunkInterface, a_OtherPlayer.GetLastBedPos(), false); + a_OtherPlayer.SetIsInBed(false); + return false; } - } + ); + a_WorldInterface.SetTimeOfDay(0); + a_ChunkInterface.SetBlockMeta(a_BlockPos, Meta & 0x0b); // Clear the "occupied" bit of the bed's block } return true; } |