1
0

Merge pull request #1734 from mc-server/pistons

Handle client 'leave bed' request
This commit is contained in:
Mattes D 2015-03-14 22:44:04 +01:00
commit 65d2ef32e9
7 changed files with 46 additions and 57 deletions

View File

@ -1,14 +1,9 @@
#include "Globals.h" #include "Globals.h"
#include "BlockBed.h" #include "BlockBed.h"
#include "BroadcastInterface.h" #include "BroadcastInterface.h"
#include "ChunkInterface.h"
#include "Entities/../World.h" #include "Entities/../World.h"
#include "Entities/Player.h" #include "Entities/Player.h"
#include "WorldInterface.h"
@ -64,21 +59,22 @@ class cPlayerBedStateUnsetter :
public cPlayerListCallback public cPlayerListCallback
{ {
public: public:
cPlayerBedStateUnsetter(Vector3i a_Position, cWorldInterface & a_WorldInterface) : cPlayerBedStateUnsetter(Vector3i a_Position, cChunkInterface & a_ChunkInterface) :
m_Position(a_Position), m_WorldInterface(a_WorldInterface) m_Position(a_Position),
m_ChunkInterface(a_ChunkInterface)
{ {
} }
virtual bool Item(cPlayer * a_Player) override virtual bool Item(cPlayer * a_Player) override
{ {
cBlockBedHandler::SetBedOccupationState(m_ChunkInterface, a_Player->GetLastBedPos(), false);
a_Player->SetIsInBed(false); a_Player->SetIsInBed(false);
m_WorldInterface.GetBroadcastManager().BroadcastEntityAnimation(*a_Player, 2);
return false; return false;
} }
private: private:
Vector3i m_Position; Vector3i m_Position;
cWorldInterface & m_WorldInterface; cChunkInterface & m_ChunkInterface;
}; };
@ -97,7 +93,7 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
if (a_WorldInterface.GetTimeOfDay() > 13000) if (a_WorldInterface.GetTimeOfDay() > 13000)
{ {
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
if (Meta & 0x4) if ((Meta & 0x4) == 0x4)
{ {
a_Player->SendMessageFailure("This bed is occupied"); a_Player->SendMessageFailure("This bed is occupied");
} }
@ -105,7 +101,7 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
{ {
Vector3i PillowDirection(0, 0, 0); Vector3i PillowDirection(0, 0, 0);
if (Meta & 0x8) if ((Meta & 0x8) == 0x8)
{ {
// Is pillow // Is pillow
a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX, a_BlockY, a_BlockZ); a_WorldInterface.GetBroadcastManager().BroadcastUseBed(*a_Player, a_BlockX, a_BlockY, a_BlockZ);
@ -122,15 +118,15 @@ void cBlockBedHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface
} }
} }
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta | 0x4); // Where 0x4 = occupied bit
a_Player->SetIsInBed(true);
a_Player->SetBedPos(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); a_Player->SetBedPos(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
SetBedOccupationState(a_ChunkInterface, a_Player->GetLastBedPos(), true);
a_Player->SetIsInBed(true);
a_Player->SendMessageSuccess("Home position set successfully"); a_Player->SendMessageSuccess("Home position set successfully");
cTimeFastForwardTester Tester; cTimeFastForwardTester Tester;
if (a_WorldInterface.ForEachPlayer(Tester)) if (a_WorldInterface.ForEachPlayer(Tester))
{ {
cPlayerBedStateUnsetter Unsetter(Vector3i(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z), a_WorldInterface); cPlayerBedStateUnsetter Unsetter(Vector3i(a_BlockX + PillowDirection.x, a_BlockY, a_BlockZ + PillowDirection.z), a_ChunkInterface);
a_WorldInterface.ForEachPlayer(Unsetter); a_WorldInterface.ForEachPlayer(Unsetter);
a_WorldInterface.SetTimeOfDay(0); a_WorldInterface.SetTimeOfDay(0);
a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0x0b); // Clear the "occupied" bit of the bed's block a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0x0b); // Clear the "occupied" bit of the bed's block

View File

@ -4,9 +4,9 @@
#include "BlockHandler.h" #include "BlockHandler.h"
#include "MetaRotator.h" #include "MetaRotator.h"
#include "Item.h" #include "Item.h"
#include "ChunkInterface.h"
class cChunkInterface;
class cPlayer; class cPlayer;
class cWorldInterface; class cWorldInterface;
@ -21,17 +21,14 @@ public:
: cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType) : cMetaRotator<cBlockHandler, 0x3, 0x02, 0x03, 0x00, 0x01, true>(a_BlockType)
{ {
} }
virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override;
virtual void 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) override; virtual void 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) override;
virtual bool IsUseable(void) override virtual bool IsUseable(void) override
{ {
return true; return true;
} }
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
@ -39,14 +36,12 @@ public:
a_Pickups.push_back(cItem(E_ITEM_BED, 1, 0)); a_Pickups.push_back(cItem(E_ITEM_BED, 1, 0));
} }
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
{ {
return true; return true;
} }
// Bed specific helper functions // Bed specific helper functions
static NIBBLETYPE RotationToMetaData(double a_Rotation) static NIBBLETYPE RotationToMetaData(double a_Rotation)
{ {
@ -61,7 +56,6 @@ public:
return ((char)a_Rotation + 2) % 4; return ((char)a_Rotation + 2) % 4;
} }
static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData) static Vector3i MetaDataToDirection(NIBBLETYPE a_MetaData)
{ {
switch (a_MetaData) switch (a_MetaData)
@ -73,6 +67,21 @@ public:
} }
return Vector3i(); return Vector3i();
} }
static void SetBedOccupationState(cChunkInterface & a_ChunkInterface, const Vector3i & a_BedPosition, bool a_IsOccupied)
{
auto Meta = a_ChunkInterface.GetBlockMeta(a_BedPosition.x, a_BedPosition.y, a_BedPosition.z);
if (a_IsOccupied)
{
Meta |= 0x04; // Where 0x4 = occupied bit
}
else
{
Meta &= 0x0b; // Clear the "occupied" bit of the bed's block
}
a_ChunkInterface.SetBlockMeta(a_BedPosition.x, a_BedPosition.y, a_BedPosition.z, Meta);
}
} ; } ;

View File

@ -1322,10 +1322,7 @@ void cChunkMap::SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYP
void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients) void cChunkMap::SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients)
{ {
cChunkInterface ChunkInterface(this); cChunkInterface ChunkInterface(this);
if (a_BlockType == E_BLOCK_AIR) BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ);
{
BlockHandler(GetBlock(a_BlockX, a_BlockY, a_BlockZ))->OnDestroyed(ChunkInterface, *m_World, a_BlockX, a_BlockY, a_BlockZ);
}
int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ; int ChunkX, ChunkZ, X = a_BlockX, Y = a_BlockY, Z = a_BlockZ;
cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ); cChunkDef::AbsoluteToRelative( X, Y, Z, ChunkX, ChunkZ);

View File

@ -21,6 +21,7 @@
#include "Items/ItemHandler.h" #include "Items/ItemHandler.h"
#include "Blocks/BlockHandler.h" #include "Blocks/BlockHandler.h"
#include "Blocks/BlockSlab.h" #include "Blocks/BlockSlab.h"
#include "Blocks/BlockBed.h"
#include "Blocks/ChunkInterface.h" #include "Blocks/ChunkInterface.h"
#include "Root.h" #include "Root.h"
@ -1501,30 +1502,6 @@ void cClientHandle::HandleAnimation(int a_Animation)
return; return;
} }
// Because the animation ID sent to servers by clients are different to those sent back, we need this
switch (a_Animation)
{
case 0: // No animation - wiki.vg doesn't say that client has something specific for it, so I suppose it will just become -1
case 1:
case 2:
case 3:
{
a_Animation--; // Offset by -1
break;
}
case 5:
case 6:
case 7:
{
a_Animation -= 2; // Offset by -2
break;
}
default: // Anything else is the same
{
break;
}
}
m_Player->GetWorld()->BroadcastEntityAnimation(*m_Player, a_Animation, this); m_Player->GetWorld()->BroadcastEntityAnimation(*m_Player, a_Animation, this);
} }
@ -1766,7 +1743,9 @@ void cClientHandle::HandleEntityLeaveBed(int a_EntityID)
return; return;
} }
m_Player->GetWorld()->BroadcastEntityAnimation(*m_Player, 2); cChunkInterface Interface(GetPlayer()->GetWorld()->GetChunkMap());
cBlockBedHandler::SetBedOccupationState(Interface, GetPlayer()->GetLastBedPos(), false);
GetPlayer()->SetIsInBed(false);
} }

View File

@ -314,8 +314,18 @@ public:
// tolua_end // tolua_end
/** Sets a player's in-bed state; we can't be sure plugins will keep this value updated, so no exporting */ /** Sets a player's in-bed state
void SetIsInBed(bool a_Flag) { m_bIsInBed = a_Flag; } We can't be sure plugins will keep this value updated, so no exporting
If value is false (not in bed), will update players of the fact that they have been ejected from the bed
*/
void SetIsInBed(bool a_Flag)
{
m_bIsInBed = a_Flag;
if (!a_Flag)
{
GetWorld()->BroadcastEntityAnimation(*this, 2);
}
}
/** Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet */ /** Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet */
void StartEating(void); void StartEating(void);

View File

@ -2105,9 +2105,7 @@ void cProtocol180::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
void cProtocol180::HandlePacketAnimation(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketAnimation(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(a_ByteBuffer, ReadBEInt, int, EntityID); m_Client->HandleAnimation(1); // Packet exists solely for arm-swing notification
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Animation);
m_Client->HandleAnimation(Animation);
} }

View File

@ -3638,7 +3638,7 @@ void cWorld::cTaskUnloadUnusedChunks::Run(cWorld & a_World)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// cWorld::cTaskSendBlockTo // cWorld::cTaskSendBlockToAllPlayers
cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue) : cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue) :
m_SendQueue(a_SendQueue) m_SendQueue(a_SendQueue)