Track skin part and main hand preferences (#3498)
This commit is contained in:
parent
45ce828a16
commit
9c2a0bb7b9
@ -11351,6 +11351,16 @@ a_Player:OpenWindow(Window);
|
||||
},
|
||||
Notes = "Returns the player's current maximum speed, relative to the game default speed. Takes into account the sprinting / flying status.",
|
||||
},
|
||||
GetMainHand =
|
||||
{
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "eMainHand",
|
||||
},
|
||||
},
|
||||
Notes = "Returns the player's main hand.",
|
||||
},
|
||||
GetName =
|
||||
{
|
||||
Returns =
|
||||
@ -11411,6 +11421,16 @@ a_Player:OpenWindow(Window);
|
||||
},
|
||||
Notes = "Returns the player's maximum sprinting speed, relative to the game default speed. Defaults to 1.3, but plugins may modify it for faster or slower sprinting.",
|
||||
},
|
||||
GetSkinParts =
|
||||
{
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Notes = "Returns the player's current set of skin part flags. This is a bitwise OR of various {{eSkinPart}} constants. Note that HasSkinPart may be easier to use in most situations.",
|
||||
},
|
||||
GetStance =
|
||||
{
|
||||
Returns =
|
||||
@ -11535,6 +11555,23 @@ a_Player:OpenWindow(Window);
|
||||
},
|
||||
Notes = "Returns true if the player has the specified permission",
|
||||
},
|
||||
HasSkinPart =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Part",
|
||||
Type = "eSkinPart",
|
||||
},
|
||||
},
|
||||
Returns =
|
||||
{
|
||||
{
|
||||
Type = "boolean",
|
||||
},
|
||||
},
|
||||
Notes = "Returns true if the player has the specified skin part enabled",
|
||||
},
|
||||
Heal =
|
||||
{
|
||||
Params =
|
||||
@ -12063,6 +12100,17 @@ a_Player:OpenWindow(Window);
|
||||
},
|
||||
Notes = "Sets the 'IsFishing' flag for the player. The floater entity ID is expected for the true variant, it can be omitted when IsFishing is false. FIXME: Undefined behavior when multiple fishing rods are used simultanously",
|
||||
},
|
||||
SetMainHand =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Hand",
|
||||
Type = "eMainHand",
|
||||
},
|
||||
},
|
||||
Notes = "Sets the main hand of the player.",
|
||||
},
|
||||
SetName =
|
||||
{
|
||||
Params =
|
||||
@ -12096,6 +12144,17 @@ a_Player:OpenWindow(Window);
|
||||
},
|
||||
Notes = "Sets whether the player is sprinting or not.",
|
||||
},
|
||||
SetSkinParts =
|
||||
{
|
||||
Params =
|
||||
{
|
||||
{
|
||||
Name = "Parts",
|
||||
Type = "number",
|
||||
},
|
||||
},
|
||||
Notes = "Sets the skin part flags of the player. The value should be a bitwise OR of several {{eSkinPart}} constants.",
|
||||
},
|
||||
SetSprintingMaxSpeed =
|
||||
{
|
||||
Params =
|
||||
@ -16632,6 +16691,54 @@ end
|
||||
{
|
||||
Notes = "Something concerning (i.e. reload) is about to happen",
|
||||
},
|
||||
hMain =
|
||||
{
|
||||
Notes = "The main hand",
|
||||
},
|
||||
hOff =
|
||||
{
|
||||
Notes = "The off hand",
|
||||
},
|
||||
mhLeft =
|
||||
{
|
||||
Notes = "The left hand is the main hand",
|
||||
},
|
||||
mhRight =
|
||||
{
|
||||
Notes = "The right hand is the main hand",
|
||||
},
|
||||
spCape =
|
||||
{
|
||||
Notes = "The cape skin part",
|
||||
},
|
||||
spJacket =
|
||||
{
|
||||
Notes = "The jacket skin part",
|
||||
},
|
||||
spLeftSleeve =
|
||||
{
|
||||
Notes = "The left sleeve skin part",
|
||||
},
|
||||
spRightSleeve =
|
||||
{
|
||||
Notes = "The right sleeve skin part",
|
||||
},
|
||||
spLeftPants =
|
||||
{
|
||||
Notes = "The left pants leg skin part",
|
||||
},
|
||||
spRightPants =
|
||||
{
|
||||
Notes = "The right pants leg skin part",
|
||||
},
|
||||
spHat =
|
||||
{
|
||||
Notes = "The hat/head skin part",
|
||||
},
|
||||
spMask =
|
||||
{
|
||||
Notes = "A mask of all valid skin parts combined",
|
||||
},
|
||||
},
|
||||
ConstantGroups =
|
||||
{
|
||||
@ -16717,6 +16824,32 @@ end
|
||||
gmXXX constants, the eGameMode_ constants are deprecated and will be removed from the API.
|
||||
]],
|
||||
},
|
||||
eHand =
|
||||
{
|
||||
Include =
|
||||
{
|
||||
"hMain",
|
||||
"hOff",
|
||||
},
|
||||
TextBefore = [[
|
||||
These constants represent the main and off hand. Currently, these constants are not used, but
|
||||
are provided for future use when dual-wielding is functional. An action or item can be in the
|
||||
main hand or the off hand. The main hand can be either the left or the right hand - use
|
||||
{{cPlayer}}:GetMainHand() to determine which (see {{eMainHand}}).
|
||||
]],
|
||||
},
|
||||
eMainHand =
|
||||
{
|
||||
Include =
|
||||
{
|
||||
"^mh.*",
|
||||
},
|
||||
TextBefore = [[
|
||||
These constants identify which hand is the main hand. The main hand can either be the left hand
|
||||
or the right hand. Note that this is only visual, as the client behaves the same regardless of the
|
||||
main hand setting. See {{cPlayer}}:GetMainHand().
|
||||
]],
|
||||
},
|
||||
EMCSBiome =
|
||||
{
|
||||
Include = "^bi.*",
|
||||
@ -16809,6 +16942,16 @@ end
|
||||
The following constants define the block types that are propelled outwards after an explosion.
|
||||
]],
|
||||
},
|
||||
eSkinPart =
|
||||
{
|
||||
Include =
|
||||
{
|
||||
"^sp.*",
|
||||
},
|
||||
TextBefore = [[
|
||||
These constants represent various skin part flags.
|
||||
]],
|
||||
},
|
||||
eSpreadSource =
|
||||
{
|
||||
Include = "^ss.*",
|
||||
|
@ -203,6 +203,42 @@ enum eMobHeadRotation
|
||||
|
||||
|
||||
|
||||
enum eHand
|
||||
{
|
||||
hMain = 0,
|
||||
hOff = 1,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum eMainHand
|
||||
{
|
||||
mhLeft = 0,
|
||||
mhRight = 1,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum eSkinPart
|
||||
{
|
||||
spCape = 0x01,
|
||||
spJacket = 0x02,
|
||||
spLeftSleeve = 0x04,
|
||||
spRightSleeve = 0x08,
|
||||
spLeftPants = 0x10,
|
||||
spRightPants = 0x20,
|
||||
spHat = 0x40,
|
||||
spMask = 0x7F,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
inline const char * ClickActionToString(int a_ClickAction)
|
||||
{
|
||||
switch (a_ClickAction)
|
||||
|
@ -90,7 +90,9 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) :
|
||||
m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL),
|
||||
m_bIsTeleporting(false),
|
||||
m_UUID((a_Client != nullptr) ? a_Client->GetUUID() : ""),
|
||||
m_CustomName("")
|
||||
m_CustomName(""),
|
||||
m_SkinParts(0),
|
||||
m_MainHand(mhRight)
|
||||
{
|
||||
ASSERT(a_PlayerName.length() <= 16); // Otherwise this player could crash many clients...
|
||||
|
||||
@ -2632,6 +2634,26 @@ bool cPlayer::PlaceBlocks(const sSetBlockVector & a_Blocks)
|
||||
|
||||
|
||||
|
||||
void cPlayer::SetSkinParts(int a_Parts)
|
||||
{
|
||||
m_SkinParts = a_Parts & spMask;
|
||||
m_World->BroadcastEntityMetadata(*this, m_ClientHandle.get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::SetMainHand(eMainHand a_Hand)
|
||||
{
|
||||
m_MainHand = a_Hand;
|
||||
m_World->BroadcastEntityMetadata(*this, m_ClientHandle.get());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cPlayer::AttachTo(cEntity * a_AttachTo)
|
||||
{
|
||||
// Different attach, if this is a spectator
|
||||
|
@ -499,6 +499,13 @@ public:
|
||||
The blocks in range (a_BlockX - a_Range, a_BlockX + a_Range) are sent (NY-metric). */
|
||||
void SendBlocksAround(int a_BlockX, int a_BlockY, int a_BlockZ, int a_Range = 1);
|
||||
|
||||
bool HasSkinPart(eSkinPart a_Part) const { return (m_SkinParts & a_Part) != 0; }
|
||||
int GetSkinParts(void) const { return m_SkinParts; }
|
||||
void SetSkinParts(int a_Parts);
|
||||
|
||||
eMainHand GetMainHand(void) const { return m_MainHand; }
|
||||
void SetMainHand(eMainHand a_Hand);
|
||||
|
||||
// tolua_end
|
||||
|
||||
/** Calls the block placement hooks and places the blocks in the world.
|
||||
@ -682,6 +689,12 @@ protected:
|
||||
|
||||
AString m_CustomName;
|
||||
|
||||
/** Displayed skin part bit mask */
|
||||
int m_SkinParts;
|
||||
|
||||
/** The main hand of the player */
|
||||
eMainHand m_MainHand;
|
||||
|
||||
/** Sets the speed and sends it to the client, so that they are forced to move so. */
|
||||
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ) override;
|
||||
|
||||
|
@ -400,6 +400,14 @@ void cProtocol_1_10_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity &
|
||||
a_Pkt.WriteBEUInt8(LIVING_HEALTH);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
|
||||
a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth()));
|
||||
|
||||
a_Pkt.WriteBEUInt8(PLAYER_DISPLAYED_SKIN_PARTS);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
|
||||
a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts()));
|
||||
|
||||
a_Pkt.WriteBEUInt8(PLAYER_MAIN_HAND);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
|
||||
a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetMainHand()));
|
||||
break;
|
||||
}
|
||||
case cEntity::etPickup:
|
||||
|
@ -2311,11 +2311,12 @@ void cProtocol_1_8_0::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
|
||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ViewDistance);
|
||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ChatFlags);
|
||||
HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors);
|
||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinFlags);
|
||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinParts);
|
||||
|
||||
m_Client->SetLocale(Locale);
|
||||
m_Client->SetViewDistance(ViewDistance);
|
||||
// TODO: Handle other values
|
||||
m_Client->GetPlayer()->SetSkinParts(SkinParts);
|
||||
// TODO: Handle chat flags and chat colors
|
||||
}
|
||||
|
||||
|
||||
@ -3234,7 +3235,20 @@ void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a
|
||||
|
||||
switch (a_Entity.GetEntityType())
|
||||
{
|
||||
case cEntity::etPlayer: break; // TODO?
|
||||
case cEntity::etPlayer:
|
||||
{
|
||||
auto & Player = reinterpret_cast<const cPlayer &>(a_Entity);
|
||||
|
||||
// Player health (not handled since players aren't monsters)
|
||||
a_Pkt.WriteBEUInt8(0x66);
|
||||
a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth()));
|
||||
|
||||
// Skin flags
|
||||
a_Pkt.WriteBEUInt8(0x0A);
|
||||
a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts()));
|
||||
|
||||
break;
|
||||
}
|
||||
case cEntity::etPickup:
|
||||
{
|
||||
a_Pkt.WriteBEUInt8((5 << 5) | 10); // Slot(5) + index 10
|
||||
|
@ -2355,12 +2355,14 @@ void cProtocol_1_9_0::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
|
||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ViewDistance);
|
||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ChatFlags);
|
||||
HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors);
|
||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinFlags);
|
||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinParts);
|
||||
HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, MainHand);
|
||||
|
||||
m_Client->SetLocale(Locale);
|
||||
m_Client->SetViewDistance(ViewDistance);
|
||||
// TODO: Handle other values
|
||||
m_Client->GetPlayer()->SetSkinParts(SkinParts);
|
||||
m_Client->GetPlayer()->SetMainHand(static_cast<eMainHand>(MainHand));
|
||||
// TODO: Handle chat flags and chat colors
|
||||
}
|
||||
|
||||
|
||||
@ -3552,9 +3554,17 @@ void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_STRING);
|
||||
a_Pkt.WriteString(Player.GetName());
|
||||
|
||||
a_Pkt.WriteBEUInt8(6); // Start metadata - Index 6: Health
|
||||
a_Pkt.WriteBEUInt8(6); // Index 6: Health
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
|
||||
a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth()));
|
||||
|
||||
a_Pkt.WriteBEUInt8(12);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
|
||||
a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts()));
|
||||
|
||||
a_Pkt.WriteBEUInt8(13);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
|
||||
a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetMainHand()));
|
||||
break;
|
||||
}
|
||||
case cEntity::etPickup:
|
||||
|
Loading…
Reference in New Issue
Block a user