Basic elytra flight (#5124)
* Basic elytra flight Co-authored-by: 12xx12 <44411062+12xx12@users.noreply.github.com> Co-authored-by: Tiger Wang <ziwei.tiger@outlook.com>
This commit is contained in:
parent
ce6f8b3557
commit
071b7be3d4
@ -4071,6 +4071,16 @@ local Hash = cCryptoHash.sha1HexString("DataToHash")
|
|||||||
},
|
},
|
||||||
Notes = "Returns true if the entity is sprinting. Entities that cannot sprint return always false",
|
Notes = "Returns true if the entity is sprinting. Entities that cannot sprint return always false",
|
||||||
},
|
},
|
||||||
|
IsElytraFlying =
|
||||||
|
{
|
||||||
|
Returns =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Type = "boolean",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Notes = "Returns true if the entity is flying with an elytra. Entities that cannot fly with an elytra return always false",
|
||||||
|
},
|
||||||
IsSubmerged =
|
IsSubmerged =
|
||||||
{
|
{
|
||||||
Returns =
|
Returns =
|
||||||
@ -10537,16 +10547,6 @@ a_Player:OpenWindow(Window);
|
|||||||
},
|
},
|
||||||
Notes = "Returns the player's current set of skin part flags. This is a bitwise OR of various {{Globals#eSkinPart|eSkinPart}} constants. Note that HasSkinPart may be easier to use in most situations.",
|
Notes = "Returns the player's current set of skin part flags. This is a bitwise OR of various {{Globals#eSkinPart|eSkinPart}} constants. Note that HasSkinPart may be easier to use in most situations.",
|
||||||
},
|
},
|
||||||
GetStance =
|
|
||||||
{
|
|
||||||
Returns =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
Type = "number",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Notes = "Returns the player's stance (Y-pos of player's eyes)",
|
|
||||||
},
|
|
||||||
GetTeam =
|
GetTeam =
|
||||||
{
|
{
|
||||||
Returns =
|
Returns =
|
||||||
@ -11277,6 +11277,17 @@ a_Player:OpenWindow(Window);
|
|||||||
},
|
},
|
||||||
Notes = "Sets the skin part flags of the player. The value should be a bitwise OR of several {{Globals#eSkinPart|eSkinPart}} constants.",
|
Notes = "Sets the skin part flags of the player. The value should be a bitwise OR of several {{Globals#eSkinPart|eSkinPart}} constants.",
|
||||||
},
|
},
|
||||||
|
SetElytraFlight =
|
||||||
|
{
|
||||||
|
Params =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Name = "IsElytraFlying",
|
||||||
|
Type = "boolean",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Notes = "Sets whether the player is elytra flying or not.",
|
||||||
|
},
|
||||||
SetSprintingMaxSpeed =
|
SetSprintingMaxSpeed =
|
||||||
{
|
{
|
||||||
Params =
|
Params =
|
||||||
|
@ -574,12 +574,9 @@ void cClientHandle::HandleNPCTrade(int a_SlotNum)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandleOpenHorseInventory(UInt32 a_EntityID)
|
void cClientHandle::HandleOpenHorseInventory()
|
||||||
{
|
{
|
||||||
if (m_Player->GetUniqueID() == a_EntityID)
|
m_Player->OpenHorseInventory();
|
||||||
{
|
|
||||||
m_Player->OpenHorseInventory();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -665,6 +662,15 @@ void cClientHandle::HandleCreativeInventory(Int16 a_SlotNum, const cItem & a_Hel
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::HandleCrouch(const bool a_IsCrouching)
|
||||||
|
{
|
||||||
|
m_Player->SetCrouch(a_IsCrouching);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment)
|
void cClientHandle::HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment)
|
||||||
{
|
{
|
||||||
if (a_Enchantment > 2)
|
if (a_Enchantment > 2)
|
||||||
@ -749,7 +755,7 @@ void cClientHandle::HandlePlayerAbilities(bool a_IsFlying, float FlyingSpeed, fl
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround)
|
void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, bool a_IsOnGround)
|
||||||
{
|
{
|
||||||
if (m_Player->IsFrozen())
|
if (m_Player->IsFrozen())
|
||||||
{
|
{
|
||||||
@ -759,7 +765,6 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ,
|
|||||||
|
|
||||||
Vector3d NewPosition(a_PosX, a_PosY, a_PosZ);
|
Vector3d NewPosition(a_PosX, a_PosY, a_PosZ);
|
||||||
Vector3d OldPosition = GetPlayer()->GetPosition();
|
Vector3d OldPosition = GetPlayer()->GetPosition();
|
||||||
double OldStance = GetPlayer()->GetStance();
|
|
||||||
auto PreviousIsOnGround = GetPlayer()->IsOnGround();
|
auto PreviousIsOnGround = GetPlayer()->IsOnGround();
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
@ -769,7 +774,6 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ,
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
(OldPosition == NewPosition) &&
|
(OldPosition == NewPosition) &&
|
||||||
(OldStance == a_Stance) &&
|
|
||||||
(PreviousIsOnGround == a_IsOnGround)
|
(PreviousIsOnGround == a_IsOnGround)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -799,7 +803,6 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ,
|
|||||||
// TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too
|
// 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(NewPosition);
|
||||||
m_Player->SetStance(a_Stance);
|
|
||||||
m_Player->SetTouchGround(a_IsOnGround);
|
m_Player->SetTouchGround(a_IsOnGround);
|
||||||
m_Player->UpdateMovementStats(NewPosition - OldPosition, PreviousIsOnGround);
|
m_Player->UpdateMovementStats(NewPosition - OldPosition, PreviousIsOnGround);
|
||||||
}
|
}
|
||||||
@ -1513,9 +1516,9 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround)
|
void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, float a_Rotation, float a_Pitch, bool a_IsOnGround)
|
||||||
{
|
{
|
||||||
HandlePlayerPos(a_PosX, a_PosY, a_PosZ, a_Stance, a_IsOnGround);
|
HandlePlayerPos(a_PosX, a_PosY, a_PosZ, a_IsOnGround);
|
||||||
HandlePlayerLook(a_Rotation, a_Pitch, a_IsOnGround);
|
HandlePlayerLook(a_Rotation, a_Pitch, a_IsOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1567,6 +1570,24 @@ void cClientHandle::HandleSpectate(const cUUID & a_PlayerUUID)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::HandleSprint(const bool a_IsSprinting)
|
||||||
|
{
|
||||||
|
m_Player->SetSprint(a_IsSprinting);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cClientHandle::HandleStartElytraFlight()
|
||||||
|
{
|
||||||
|
m_Player->SetElytraFlight(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandleSteerVehicle(float a_Forward, float a_Sideways)
|
void cClientHandle::HandleSteerVehicle(float a_Forward, float a_Sideways)
|
||||||
{
|
{
|
||||||
m_Player->SteerVehicle(a_Forward, a_Sideways);
|
m_Player->SteerVehicle(a_Forward, a_Sideways);
|
||||||
@ -1831,47 +1852,11 @@ bool cClientHandle::HandleHandshake(const AString & a_Username)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandleEntityCrouch(UInt32 a_EntityID, bool a_IsCrouching)
|
void cClientHandle::HandleLeaveBed()
|
||||||
{
|
{
|
||||||
if (a_EntityID != m_Player->GetUniqueID())
|
cChunkInterface Interface(m_Player->GetWorld()->GetChunkMap());
|
||||||
{
|
cBlockBedHandler::SetBedOccupationState(Interface, m_Player->GetLastBedPos(), false);
|
||||||
// We should only receive entity actions from the entity that is performing the action
|
m_Player->SetIsInBed(false);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Player->SetCrouch(a_IsCrouching);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandleEntityLeaveBed(UInt32 a_EntityID)
|
|
||||||
{
|
|
||||||
if (a_EntityID != m_Player->GetUniqueID())
|
|
||||||
{
|
|
||||||
// We should only receive entity actions from the entity that is performing the action
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cChunkInterface Interface(GetPlayer()->GetWorld()->GetChunkMap());
|
|
||||||
cBlockBedHandler::SetBedOccupationState(Interface, GetPlayer()->GetLastBedPos(), false);
|
|
||||||
GetPlayer()->SetIsInBed(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cClientHandle::HandleEntitySprinting(UInt32 a_EntityID, bool a_IsSprinting)
|
|
||||||
{
|
|
||||||
if (a_EntityID != m_Player->GetUniqueID())
|
|
||||||
{
|
|
||||||
// We should only receive entity actions from the entity that is performing the action
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Player->SetSprint(a_IsSprinting);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -322,13 +322,12 @@ public: // tolua_export
|
|||||||
a_ClickAction specifies whether the click was inside the window or not (caLeftClick or caLeftClickOutside). */
|
a_ClickAction specifies whether the click was inside the window or not (caLeftClick or caLeftClickOutside). */
|
||||||
void HandleCreativeInventory(Int16 a_SlotNum, const cItem & a_HeldItem, eClickAction a_ClickAction);
|
void HandleCreativeInventory(Int16 a_SlotNum, const cItem & a_HeldItem, eClickAction a_ClickAction);
|
||||||
|
|
||||||
|
/** Handles a player sneaking or unsneaking. */
|
||||||
|
void HandleCrouch(bool a_IsCrouching);
|
||||||
|
|
||||||
/** Called when the player enchants an Item in the Enchanting table UI. */
|
/** Called when the player enchants an Item in the Enchanting table UI. */
|
||||||
void HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment);
|
void HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment);
|
||||||
|
|
||||||
void HandleEntityCrouch (UInt32 a_EntityID, bool a_IsCrouching);
|
|
||||||
void HandleEntityLeaveBed (UInt32 a_EntityID);
|
|
||||||
void HandleEntitySprinting (UInt32 a_EntityID, bool a_IsSprinting);
|
|
||||||
|
|
||||||
/** Kicks the client if the same username is already logged in.
|
/** Kicks the client if the same username is already logged in.
|
||||||
Returns false if the client has been kicked, true otherwise. */
|
Returns false if the client has been kicked, true otherwise. */
|
||||||
bool CheckMultiLogin(const AString & a_Username);
|
bool CheckMultiLogin(const AString & a_Username);
|
||||||
@ -339,6 +338,9 @@ public: // tolua_export
|
|||||||
*/
|
*/
|
||||||
bool HandleHandshake (const AString & a_Username);
|
bool HandleHandshake (const AString & a_Username);
|
||||||
|
|
||||||
|
/** Handles a player exiting his bed. */
|
||||||
|
void HandleLeaveBed();
|
||||||
|
|
||||||
void HandleKeepAlive (UInt32 a_KeepAliveID);
|
void HandleKeepAlive (UInt32 a_KeepAliveID);
|
||||||
void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, UInt8 a_Status);
|
void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, UInt8 a_Status);
|
||||||
|
|
||||||
@ -346,20 +348,19 @@ public: // tolua_export
|
|||||||
the NPC UI. */
|
the NPC UI. */
|
||||||
void HandleNPCTrade(int a_SlotNum);
|
void HandleNPCTrade(int a_SlotNum);
|
||||||
|
|
||||||
/** Handles a player opening their inventory while riding a horse.
|
/** Handles a player opening his inventory while riding a horse. */
|
||||||
@param a_EntityID ID of the player that is to open the inventory. Should be the same as GetPlayer()->GetUniqueID(). */
|
void HandleOpenHorseInventory();
|
||||||
void HandleOpenHorseInventory(UInt32 a_EntityID);
|
|
||||||
|
|
||||||
void HandlePing (void);
|
void HandlePing (void);
|
||||||
void HandlePlayerAbilities (bool a_IsFlying, float FlyingSpeed, float WalkingSpeed);
|
void HandlePlayerAbilities (bool a_IsFlying, float FlyingSpeed, float WalkingSpeed);
|
||||||
void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround);
|
void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround);
|
||||||
void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay)
|
void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay)
|
||||||
|
|
||||||
/** Verifies and sets player position, performing relevant checks
|
/** Verifies and sets player position, performing relevant checks
|
||||||
Calls relevant methods to process movement related statistics
|
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
|
Requires state of previous position and on-ground status, so must be called when these are still intact
|
||||||
*/
|
*/
|
||||||
void HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround);
|
void HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, bool a_IsOnGround);
|
||||||
|
|
||||||
|
|
||||||
void HandlePluginMessage (const AString & a_Channel, ContiguousByteBufferView a_Message);
|
void HandlePluginMessage (const AString & a_Channel, ContiguousByteBufferView a_Message);
|
||||||
@ -367,6 +368,13 @@ public: // tolua_export
|
|||||||
void HandleRightClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, eHand a_Hand);
|
void HandleRightClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, eHand a_Hand);
|
||||||
void HandleSlotSelected (Int16 a_SlotNum);
|
void HandleSlotSelected (Int16 a_SlotNum);
|
||||||
void HandleSpectate (const cUUID & a_PlayerUUID);
|
void HandleSpectate (const cUUID & a_PlayerUUID);
|
||||||
|
|
||||||
|
/** Handles a player sprinting or slowing back down. */
|
||||||
|
void HandleSprint(bool a_IsSprinting);
|
||||||
|
|
||||||
|
/** Handles a player starting elytra flight while falling. */
|
||||||
|
void HandleStartElytraFlight();
|
||||||
|
|
||||||
void HandleSteerVehicle (float Forward, float Sideways);
|
void HandleSteerVehicle (float Forward, float Sideways);
|
||||||
void HandleTabCompletion (const AString & a_Text);
|
void HandleTabCompletion (const AString & a_Text);
|
||||||
void HandleUpdateSign (
|
void HandleUpdateSign (
|
||||||
|
@ -535,6 +535,7 @@ bool ItemCategory::IsHelmet(short a_ItemType)
|
|||||||
bool ItemCategory::IsChestPlate(short a_ItemType)
|
bool ItemCategory::IsChestPlate(short a_ItemType)
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
|
(a_ItemType == E_ITEM_ELYTRA) ||
|
||||||
(a_ItemType == E_ITEM_LEATHER_TUNIC) ||
|
(a_ItemType == E_ITEM_LEATHER_TUNIC) ||
|
||||||
(a_ItemType == E_ITEM_GOLD_CHESTPLATE) ||
|
(a_ItemType == E_ITEM_GOLD_CHESTPLATE) ||
|
||||||
(a_ItemType == E_ITEM_CHAIN_CHESTPLATE) ||
|
(a_ItemType == E_ITEM_CHAIN_CHESTPLATE) ||
|
||||||
|
@ -59,6 +59,8 @@ cEntity::cEntity(eEntityType a_EntityType, Vector3d a_Pos, double a_Width, doubl
|
|||||||
m_IsInLava(false),
|
m_IsInLava(false),
|
||||||
m_IsInWater(false),
|
m_IsInWater(false),
|
||||||
m_IsHeadInWater(false),
|
m_IsHeadInWater(false),
|
||||||
|
m_Width(a_Width),
|
||||||
|
m_Height(a_Height),
|
||||||
m_AirLevel(MAX_AIR_LEVEL),
|
m_AirLevel(MAX_AIR_LEVEL),
|
||||||
m_AirTickTimer(DROWNING_TICKS),
|
m_AirTickTimer(DROWNING_TICKS),
|
||||||
m_TicksAlive(0),
|
m_TicksAlive(0),
|
||||||
@ -69,8 +71,6 @@ cEntity::cEntity(eEntityType a_EntityType, Vector3d a_Pos, double a_Width, doubl
|
|||||||
m_Position(a_Pos),
|
m_Position(a_Pos),
|
||||||
m_WaterSpeed(0, 0, 0),
|
m_WaterSpeed(0, 0, 0),
|
||||||
m_Mass (0.001), // Default 1g
|
m_Mass (0.001), // Default 1g
|
||||||
m_Width(a_Width),
|
|
||||||
m_Height(a_Height),
|
|
||||||
m_InvulnerableTicks(0)
|
m_InvulnerableTicks(0)
|
||||||
{
|
{
|
||||||
m_WorldChangeInfo.m_NewWorld = nullptr;
|
m_WorldChangeInfo.m_NewWorld = nullptr;
|
||||||
@ -2028,15 +2028,6 @@ void cEntity::SetHeadYaw(double a_HeadYaw)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::SetHeight(double a_Height)
|
|
||||||
{
|
|
||||||
m_Height = a_Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::SetMass(double a_Mass)
|
void cEntity::SetMass(double a_Mass)
|
||||||
{
|
{
|
||||||
// Make sure that mass is not zero. 1g is the default because we
|
// Make sure that mass is not zero. 1g is the default because we
|
||||||
@ -2118,15 +2109,6 @@ void cEntity::SetSpeedZ(double a_SpeedZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::SetWidth(double a_Width)
|
|
||||||
{
|
|
||||||
m_Width = a_Width;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cEntity::AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeedZ)
|
void cEntity::AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeedZ)
|
||||||
{
|
{
|
||||||
SetSpeed(m_Speed.x + a_AddSpeedX, m_Speed.y + a_AddSpeedY, m_Speed.z + a_AddSpeedZ);
|
SetSpeed(m_Speed.x + a_AddSpeedX, m_Speed.y + a_AddSpeedY, m_Speed.z + a_AddSpeedZ);
|
||||||
|
@ -328,10 +328,6 @@ public:
|
|||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
void SetHeight(double a_Height);
|
|
||||||
|
|
||||||
void SetWidth(double a_Width);
|
|
||||||
|
|
||||||
/** Exported in ManualBindings */
|
/** Exported in ManualBindings */
|
||||||
const Vector3d & GetPosition(void) const { return m_Position; }
|
const Vector3d & GetPosition(void) const { return m_Position; }
|
||||||
|
|
||||||
@ -522,12 +518,13 @@ public:
|
|||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
// COMMON metadata flags; descendants may override the defaults:
|
// COMMON metadata flags; descendants may override the defaults:
|
||||||
virtual bool IsOnFire (void) const {return (m_TicksLeftBurning > 0); }
|
virtual bool IsCrouched (void) const { return false; }
|
||||||
virtual bool IsCrouched (void) const {return false; }
|
virtual bool IsElytraFlying(void) const { return false; }
|
||||||
virtual bool IsRiding (void) const {return false; }
|
virtual bool IsInvisible (void) const { return false; }
|
||||||
virtual bool IsSprinting(void) const {return false; }
|
virtual bool IsOnFire (void) const { return m_TicksLeftBurning > 0; }
|
||||||
virtual bool IsRclking (void) const {return false; }
|
virtual bool IsRclking (void) const { return false; }
|
||||||
virtual bool IsInvisible(void) const { return false; }
|
virtual bool IsRiding (void) const { return false; }
|
||||||
|
virtual bool IsSprinting (void) const { return false; }
|
||||||
|
|
||||||
/** Returns true if any part of the entity is in a fire block */
|
/** Returns true if any part of the entity is in a fire block */
|
||||||
virtual bool IsInFire(void) const { return m_IsInFire; }
|
virtual bool IsInFire(void) const { return m_IsInFire; }
|
||||||
@ -689,6 +686,12 @@ protected:
|
|||||||
/** If the entity's head is in a water block */
|
/** If the entity's head is in a water block */
|
||||||
bool m_IsHeadInWater;
|
bool m_IsHeadInWater;
|
||||||
|
|
||||||
|
/** Width of the entity, in the XZ plane. Since entities are represented as cylinders, this is more of a diameter. */
|
||||||
|
double m_Width;
|
||||||
|
|
||||||
|
/** Height of the entity (Y axis). */
|
||||||
|
double m_Height;
|
||||||
|
|
||||||
/** Air level of a mobile */
|
/** Air level of a mobile */
|
||||||
int m_AirLevel;
|
int m_AirLevel;
|
||||||
int m_AirTickTimer;
|
int m_AirTickTimer;
|
||||||
@ -745,12 +748,6 @@ private:
|
|||||||
/** Measured in Kilograms (Kg) */
|
/** Measured in Kilograms (Kg) */
|
||||||
double m_Mass;
|
double m_Mass;
|
||||||
|
|
||||||
/** Width of the entity, in the XZ plane. Since entities are represented as cylinders, this is more of a diameter. */
|
|
||||||
double m_Width;
|
|
||||||
|
|
||||||
/** Height of the entity (Y axis) */
|
|
||||||
double m_Height;
|
|
||||||
|
|
||||||
/** If a player hit a entity, the entity receive a invulnerable of 10 ticks.
|
/** If a player hit a entity, the entity receive a invulnerable of 10 ticks.
|
||||||
While this ticks, a player can't hit this entity. */
|
While this ticks, a player can't hit this entity. */
|
||||||
int m_InvulnerableTicks;
|
int m_InvulnerableTicks;
|
||||||
|
@ -106,8 +106,6 @@ cMinecart::cMinecart(ePayload a_Payload, Vector3d a_Pos):
|
|||||||
SetAirDrag(0.05f);
|
SetAirDrag(0.05f);
|
||||||
SetMaxHealth(6);
|
SetMaxHealth(6);
|
||||||
SetHealth(6);
|
SetHealth(6);
|
||||||
SetWidth(1);
|
|
||||||
SetHeight(0.9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1274,10 +1272,10 @@ void cMinecart::ApplyAcceleration(Vector3d a_ForwardDirection, double a_Accelera
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cRideableMinecart:
|
// cRideableMinecart:
|
||||||
|
|
||||||
cRideableMinecart::cRideableMinecart(Vector3d a_Pos, const cItem & a_Content, int a_Height):
|
cRideableMinecart::cRideableMinecart(Vector3d a_Pos, const cItem & a_Content, int a_ContentHeight):
|
||||||
Super(mpNone, a_Pos),
|
Super(mpNone, a_Pos),
|
||||||
m_Content(a_Content),
|
m_Content(a_Content),
|
||||||
m_Height(a_Height)
|
m_ContentHeight(a_ContentHeight)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,10 +105,10 @@ public:
|
|||||||
|
|
||||||
CLASS_PROTODEF(cRideableMinecart)
|
CLASS_PROTODEF(cRideableMinecart)
|
||||||
|
|
||||||
cRideableMinecart(Vector3d a_Pos, const cItem & a_Content, int a_Height);
|
cRideableMinecart(Vector3d a_Pos, const cItem & a_Content, int a_ContentHeight);
|
||||||
|
|
||||||
const cItem & GetContent(void) const {return m_Content;}
|
const cItem & GetContent(void) const { return m_Content; }
|
||||||
int GetBlockHeight(void) const {return m_Height;}
|
int GetBlockHeight(void) const { return m_ContentHeight; }
|
||||||
|
|
||||||
// cEntity overrides:
|
// cEntity overrides:
|
||||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
||||||
@ -116,9 +116,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
cItem m_Content;
|
cItem m_Content;
|
||||||
int m_Height;
|
int m_ContentHeight;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -418,6 +418,11 @@ void cPawn::HandleFalling(void)
|
|||||||
auto Damage = static_cast<int>(m_LastGroundHeight - GetPosY() - 3.0);
|
auto Damage = static_cast<int>(m_LastGroundHeight - GetPosY() - 3.0);
|
||||||
if ((Damage > 0) && !FallDamageAbsorbed)
|
if ((Damage > 0) && !FallDamageAbsorbed)
|
||||||
{
|
{
|
||||||
|
if (IsElytraFlying())
|
||||||
|
{
|
||||||
|
Damage = static_cast<int>(static_cast<float>(Damage) * 0.33);
|
||||||
|
}
|
||||||
|
|
||||||
TakeDamage(dtFalling, nullptr, Damage, static_cast<float>(Damage), 0);
|
TakeDamage(dtFalling, nullptr, Damage, static_cast<float>(Damage), 0);
|
||||||
|
|
||||||
// Fall particles
|
// Fall particles
|
||||||
|
@ -66,38 +66,72 @@ const int cPlayer::EATING_TICKS = 30;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cPlayer::BodyStanceCrouching::BodyStanceCrouching(cPlayer & a_Player)
|
||||||
|
{
|
||||||
|
a_Player.SetSize(0.6f, 1.65f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cPlayer::BodyStanceSleeping::BodyStanceSleeping(cPlayer & a_Player)
|
||||||
|
{
|
||||||
|
a_Player.SetSize(0.2f, 0.2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cPlayer::BodyStanceStanding::BodyStanceStanding(cPlayer & a_Player)
|
||||||
|
{
|
||||||
|
a_Player.SetSize(0.6f, 1.8f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cPlayer::BodyStanceGliding::BodyStanceGliding(cPlayer & a_Player) :
|
||||||
|
TicksElytraFlying(0)
|
||||||
|
{
|
||||||
|
a_Player.SetSize(0.6f, 0.6f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cPlayer::cPlayer(const std::shared_ptr<cClientHandle> & a_Client) :
|
cPlayer::cPlayer(const std::shared_ptr<cClientHandle> & a_Client) :
|
||||||
Super(etPlayer, 0.6, 1.8),
|
Super(etPlayer, 0.6, 1.8),
|
||||||
m_bVisible(true),
|
m_BodyStance(BodyStanceStanding(*this)),
|
||||||
m_FoodLevel(MAX_FOOD_LEVEL),
|
m_FoodLevel(MAX_FOOD_LEVEL),
|
||||||
m_FoodSaturationLevel(5.0),
|
m_FoodSaturationLevel(5.0),
|
||||||
m_FoodTickTimer(0),
|
m_FoodTickTimer(0),
|
||||||
m_FoodExhaustionLevel(0.0),
|
m_FoodExhaustionLevel(0.0),
|
||||||
m_Stance(0.0),
|
|
||||||
m_Inventory(*this),
|
m_Inventory(*this),
|
||||||
m_EnderChestContents(9, 3),
|
m_EnderChestContents(9, 3),
|
||||||
m_DefaultWorldPath(cRoot::Get()->GetDefaultWorld()->GetDataPath()),
|
m_DefaultWorldPath(cRoot::Get()->GetDefaultWorld()->GetDataPath()),
|
||||||
m_GameMode(eGameMode_NotSet),
|
m_GameMode(eGameMode_NotSet),
|
||||||
m_ClientHandle(a_Client),
|
m_ClientHandle(a_Client),
|
||||||
m_IsFrozen(false),
|
|
||||||
m_NormalMaxSpeed(1.0),
|
m_NormalMaxSpeed(1.0),
|
||||||
m_SprintingMaxSpeed(1.3),
|
m_SprintingMaxSpeed(1.3),
|
||||||
m_FlyingMaxSpeed(1.0),
|
m_FlyingMaxSpeed(1.0),
|
||||||
m_IsCrouched(false),
|
m_IsChargingBow(false),
|
||||||
m_IsSprinting(false),
|
|
||||||
m_IsFlying(false),
|
|
||||||
m_IsFishing(false),
|
m_IsFishing(false),
|
||||||
m_CanFly(false),
|
m_IsFlightCapable(false),
|
||||||
|
m_IsFlying(false),
|
||||||
|
m_IsFrozen(false),
|
||||||
|
m_IsTeleporting(false),
|
||||||
|
m_IsVisible(true),
|
||||||
m_EatingFinishTick(-1),
|
m_EatingFinishTick(-1),
|
||||||
m_LifetimeTotalXp(0),
|
m_LifetimeTotalXp(0),
|
||||||
m_CurrentXp(0),
|
m_CurrentXp(0),
|
||||||
m_IsChargingBow(false),
|
|
||||||
m_BowCharge(0),
|
m_BowCharge(0),
|
||||||
m_FloaterID(cEntity::INVALID_ID),
|
m_FloaterID(cEntity::INVALID_ID),
|
||||||
m_Team(nullptr),
|
m_Team(nullptr),
|
||||||
m_bIsInBed(false),
|
|
||||||
m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL),
|
m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL),
|
||||||
m_bIsTeleporting(false),
|
|
||||||
m_SkinParts(0),
|
m_SkinParts(0),
|
||||||
m_MainHand(mhRight)
|
m_MainHand(mhRight)
|
||||||
{
|
{
|
||||||
@ -114,26 +148,25 @@ cPlayer::cPlayer(const std::shared_ptr<cClientHandle> & a_Client) :
|
|||||||
LoadFromDisk(World);
|
LoadFromDisk(World);
|
||||||
|
|
||||||
m_LastGroundHeight = static_cast<float>(GetPosY());
|
m_LastGroundHeight = static_cast<float>(GetPosY());
|
||||||
m_Stance = GetPosY() + 1.62;
|
|
||||||
|
|
||||||
if (m_GameMode == gmNotSet)
|
if (m_GameMode == gmNotSet)
|
||||||
{
|
{
|
||||||
if (World->IsGameModeCreative())
|
if (World->IsGameModeCreative())
|
||||||
{
|
{
|
||||||
m_CanFly = true;
|
m_IsFlightCapable = true;
|
||||||
}
|
}
|
||||||
if (World->IsGameModeSpectator()) // Otherwise Player will fall out of the world on join
|
if (World->IsGameModeSpectator()) // Otherwise Player will fall out of the world on join
|
||||||
{
|
{
|
||||||
m_CanFly = true;
|
m_IsFlightCapable = true;
|
||||||
m_IsFlying = true;
|
m_IsFlying = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_GameMode == gmSpectator) // If player is reconnecting to the server in spectator mode
|
if (m_GameMode == gmSpectator) // If player is reconnecting to the server in spectator mode
|
||||||
{
|
{
|
||||||
m_CanFly = true;
|
m_IsFlightCapable = true;
|
||||||
m_IsFlying = true;
|
m_IsFlying = true;
|
||||||
m_bVisible = false;
|
m_IsVisible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,6 +460,24 @@ void cPlayer::AddFoodExhaustion(double a_Exhaustion)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cPlayer::IsInBed(void) const
|
||||||
|
{
|
||||||
|
return std::holds_alternative<BodyStanceSleeping>(m_BodyStance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cPlayer::IsStanding() const
|
||||||
|
{
|
||||||
|
return std::holds_alternative<BodyStanceStanding>(m_BodyStance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::TossItems(const cItems & a_Items)
|
void cPlayer::TossItems(const cItems & a_Items)
|
||||||
{
|
{
|
||||||
if (IsGameModeSpectator()) // Players can't toss items in spectator
|
if (IsGameModeSpectator()) // Players can't toss items in spectator
|
||||||
@ -445,6 +496,23 @@ void cPlayer::TossItems(const cItems & a_Items)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cPlayer::SetIsInBed(const bool a_GoToBed)
|
||||||
|
{
|
||||||
|
if (a_GoToBed && IsStanding())
|
||||||
|
{
|
||||||
|
m_BodyStance = BodyStanceSleeping(*this);
|
||||||
|
}
|
||||||
|
else if (!a_GoToBed && IsInBed())
|
||||||
|
{
|
||||||
|
m_BodyStance = BodyStanceStanding(*this);
|
||||||
|
GetWorld()->BroadcastEntityAnimation(*this, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::StartEating(void)
|
void cPlayer::StartEating(void)
|
||||||
{
|
{
|
||||||
// Set the timer:
|
// Set the timer:
|
||||||
@ -525,11 +593,11 @@ const cSlotNums & cPlayer::GetInventoryPaintSlots(void) const
|
|||||||
|
|
||||||
double cPlayer::GetMaxSpeed(void) const
|
double cPlayer::GetMaxSpeed(void) const
|
||||||
{
|
{
|
||||||
if (m_IsFlying)
|
if (IsFlying())
|
||||||
{
|
{
|
||||||
return m_FlyingMaxSpeed;
|
return m_FlyingMaxSpeed;
|
||||||
}
|
}
|
||||||
else if (m_IsSprinting)
|
else if (IsSprinting())
|
||||||
{
|
{
|
||||||
return m_SprintingMaxSpeed;
|
return m_SprintingMaxSpeed;
|
||||||
}
|
}
|
||||||
@ -546,7 +614,7 @@ double cPlayer::GetMaxSpeed(void) const
|
|||||||
void cPlayer::SetNormalMaxSpeed(double a_Speed)
|
void cPlayer::SetNormalMaxSpeed(double a_Speed)
|
||||||
{
|
{
|
||||||
m_NormalMaxSpeed = a_Speed;
|
m_NormalMaxSpeed = a_Speed;
|
||||||
if (!m_IsSprinting && !m_IsFlying && !m_IsFrozen)
|
if (!IsSprinting() && !IsFlying() && !IsFrozen())
|
||||||
{
|
{
|
||||||
// If we are frozen, we do not send this yet. We send when unfreeze() is called
|
// If we are frozen, we do not send this yet. We send when unfreeze() is called
|
||||||
m_ClientHandle->SendPlayerMaxSpeed();
|
m_ClientHandle->SendPlayerMaxSpeed();
|
||||||
@ -560,7 +628,7 @@ void cPlayer::SetNormalMaxSpeed(double a_Speed)
|
|||||||
void cPlayer::SetSprintingMaxSpeed(double a_Speed)
|
void cPlayer::SetSprintingMaxSpeed(double a_Speed)
|
||||||
{
|
{
|
||||||
m_SprintingMaxSpeed = a_Speed;
|
m_SprintingMaxSpeed = a_Speed;
|
||||||
if (m_IsSprinting && !m_IsFlying && !m_IsFrozen)
|
if (IsSprinting() && !m_IsFlying && !m_IsFrozen)
|
||||||
{
|
{
|
||||||
// If we are frozen, we do not send this yet. We send when unfreeze() is called
|
// If we are frozen, we do not send this yet. We send when unfreeze() is called
|
||||||
m_ClientHandle->SendPlayerMaxSpeed();
|
m_ClientHandle->SendPlayerMaxSpeed();
|
||||||
@ -587,21 +655,18 @@ void cPlayer::SetFlyingMaxSpeed(double a_Speed)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::SetCrouch(bool a_IsCrouched)
|
void cPlayer::SetCrouch(const bool a_ShouldCrouch)
|
||||||
{
|
{
|
||||||
// Set the crouch status, broadcast to all visible players
|
if (a_ShouldCrouch && IsStanding())
|
||||||
if (a_IsCrouched == m_IsCrouched)
|
|
||||||
{
|
|
||||||
// No change
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a_IsCrouched)
|
|
||||||
{
|
{
|
||||||
|
m_BodyStance = BodyStanceCrouching(*this);
|
||||||
cRoot::Get()->GetPluginManager()->CallHookPlayerCrouched(*this);
|
cRoot::Get()->GetPluginManager()->CallHookPlayerCrouched(*this);
|
||||||
}
|
}
|
||||||
|
else if (!a_ShouldCrouch && IsCrouched())
|
||||||
|
{
|
||||||
|
m_BodyStance = BodyStanceStanding(*this);
|
||||||
|
}
|
||||||
|
|
||||||
m_IsCrouched = a_IsCrouched;
|
|
||||||
m_World->BroadcastEntityMetadata(*this);
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,16 +674,55 @@ void cPlayer::SetCrouch(bool a_IsCrouched)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::SetSprint(bool a_IsSprinting)
|
void cPlayer::SetElytraFlight(const bool a_ShouldElytraFly)
|
||||||
{
|
{
|
||||||
if (a_IsSprinting == m_IsSprinting)
|
if (a_ShouldElytraFly && IsStanding() && !IsOnGround() && !IsInWater() && !IsRiding() && (GetEquippedChestplate().m_ItemType == E_ITEM_ELYTRA))
|
||||||
|
{
|
||||||
|
m_BodyStance = BodyStanceGliding(*this);
|
||||||
|
}
|
||||||
|
else if (!a_ShouldElytraFly && IsElytraFlying())
|
||||||
|
{
|
||||||
|
m_BodyStance = BodyStanceStanding(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cPlayer::SetFlying(const bool a_ShouldFly)
|
||||||
|
{
|
||||||
|
if (a_ShouldFly == m_IsFlying)
|
||||||
{
|
{
|
||||||
// No change
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_IsSprinting = a_IsSprinting;
|
m_IsFlying = a_ShouldFly;
|
||||||
m_ClientHandle->SendPlayerMaxSpeed();
|
if (!m_IsFrozen)
|
||||||
|
{
|
||||||
|
// If we are frozen, we do not send this yet. We send when unfreeze() is called
|
||||||
|
m_ClientHandle->SendPlayerAbilities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cPlayer::SetSprint(const bool a_ShouldSprint)
|
||||||
|
{
|
||||||
|
if (a_ShouldSprint && IsStanding())
|
||||||
|
{
|
||||||
|
m_BodyStance = BodyStanceSprinting();
|
||||||
|
}
|
||||||
|
else if (!a_ShouldSprint && IsSprinting())
|
||||||
|
{
|
||||||
|
m_BodyStance = BodyStanceStanding(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -627,12 +731,12 @@ void cPlayer::SetSprint(bool a_IsSprinting)
|
|||||||
|
|
||||||
void cPlayer::SetCanFly(bool a_CanFly)
|
void cPlayer::SetCanFly(bool a_CanFly)
|
||||||
{
|
{
|
||||||
if (a_CanFly == m_CanFly)
|
if (a_CanFly == m_IsFlightCapable)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CanFly = a_CanFly;
|
m_IsFlightCapable = a_CanFly;
|
||||||
m_ClientHandle->SendPlayerAbilities();
|
m_ClientHandle->SendPlayerAbilities();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,25 +802,6 @@ cWorld * cPlayer::GetBedWorld()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::SetFlying(bool a_IsFlying)
|
|
||||||
{
|
|
||||||
if (a_IsFlying == m_IsFlying)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_IsFlying = a_IsFlying;
|
|
||||||
if (!m_IsFrozen)
|
|
||||||
{
|
|
||||||
// If we are frozen, we do not send this yet. We send when unfreeze() is called
|
|
||||||
m_ClientHandle->SendPlayerAbilities();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved)
|
void cPlayer::NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved)
|
||||||
{
|
{
|
||||||
ASSERT(a_Opponent != nullptr);
|
ASSERT(a_Opponent != nullptr);
|
||||||
@ -750,7 +835,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI)
|
|||||||
return; // not dead yet =]
|
return; // not dead yet =]
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bVisible = false; // So new clients don't see the player
|
m_IsVisible = false; // So new clients don't see the player
|
||||||
|
|
||||||
// Detach player from object / entity. If the player dies, the server still says
|
// Detach player from object / entity. If the player dies, the server still says
|
||||||
// that the player is attached to the entity / object
|
// that the player is attached to the entity / object
|
||||||
@ -905,7 +990,7 @@ void cPlayer::Respawn(void)
|
|||||||
|
|
||||||
double cPlayer::GetEyeHeight(void) const
|
double cPlayer::GetEyeHeight(void) const
|
||||||
{
|
{
|
||||||
return m_Stance;
|
return GetEyePosition().y - GetPosY();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -914,7 +999,22 @@ double cPlayer::GetEyeHeight(void) const
|
|||||||
|
|
||||||
Vector3d cPlayer::GetEyePosition(void) const
|
Vector3d cPlayer::GetEyePosition(void) const
|
||||||
{
|
{
|
||||||
return Vector3d( GetPosX(), m_Stance, GetPosZ());
|
if (IsCrouched())
|
||||||
|
{
|
||||||
|
return GetPosition().addedY(1.54);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsElytraFlying())
|
||||||
|
{
|
||||||
|
return GetPosition().addedY(0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsInBed())
|
||||||
|
{
|
||||||
|
return GetPosition().addedY(0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetPosition().addedY(1.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1314,7 +1414,7 @@ void cPlayer::TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ)
|
|||||||
{
|
{
|
||||||
SetPosition({a_PosX, a_PosY, a_PosZ});
|
SetPosition({a_PosX, a_PosY, a_PosZ});
|
||||||
FreezeInternal(GetPosition(), false);
|
FreezeInternal(GetPosition(), false);
|
||||||
m_bIsTeleporting = true;
|
m_IsTeleporting = true;
|
||||||
|
|
||||||
m_ClientHandle->SendPlayerMoveLook();
|
m_ClientHandle->SendPlayerMoveLook();
|
||||||
}
|
}
|
||||||
@ -1344,6 +1444,11 @@ bool cPlayer::IsFrozen()
|
|||||||
|
|
||||||
void cPlayer::Unfreeze()
|
void cPlayer::Unfreeze()
|
||||||
{
|
{
|
||||||
|
if (IsElytraFlying())
|
||||||
|
{
|
||||||
|
m_World->BroadcastEntityMetadata(*this);
|
||||||
|
}
|
||||||
|
|
||||||
GetClientHandle()->SendPlayerAbilities();
|
GetClientHandle()->SendPlayerAbilities();
|
||||||
GetClientHandle()->SendPlayerMaxSpeed();
|
GetClientHandle()->SendPlayerMaxSpeed();
|
||||||
|
|
||||||
@ -1449,14 +1554,14 @@ void cPlayer::ForceSetSpeed(const Vector3d & a_Speed)
|
|||||||
void cPlayer::SetVisible(bool a_bVisible)
|
void cPlayer::SetVisible(bool a_bVisible)
|
||||||
{
|
{
|
||||||
// Need to Check if the player or other players are in gamemode spectator, but will break compatibility
|
// Need to Check if the player or other players are in gamemode spectator, but will break compatibility
|
||||||
if (a_bVisible && !m_bVisible) // Make visible
|
if (a_bVisible && !m_IsVisible) // Make visible
|
||||||
{
|
{
|
||||||
m_bVisible = true;
|
m_IsVisible = true;
|
||||||
m_World->BroadcastSpawnEntity(*this);
|
m_World->BroadcastSpawnEntity(*this);
|
||||||
}
|
}
|
||||||
if (!a_bVisible && m_bVisible)
|
if (!a_bVisible && m_IsVisible)
|
||||||
{
|
{
|
||||||
m_bVisible = false;
|
m_IsVisible = false;
|
||||||
m_World->BroadcastDestroyEntity(*this, m_ClientHandle.get()); // Destroy on all clients
|
m_World->BroadcastDestroyEntity(*this, m_ClientHandle.get()); // Destroy on all clients
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1809,7 +1914,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World)
|
|||||||
|
|
||||||
if (m_GameMode == eGameMode_Creative)
|
if (m_GameMode == eGameMode_Creative)
|
||||||
{
|
{
|
||||||
m_CanFly = true;
|
m_IsFlightCapable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Inventory.LoadFromJson(Root["inventory"]);
|
m_Inventory.LoadFromJson(Root["inventory"]);
|
||||||
@ -2141,9 +2246,9 @@ bool cPlayer::IsClimbing(void) const
|
|||||||
|
|
||||||
void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIsOnGround)
|
void cPlayer::UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIsOnGround)
|
||||||
{
|
{
|
||||||
if (m_bIsTeleporting)
|
if (m_IsTeleporting)
|
||||||
{
|
{
|
||||||
m_bIsTeleporting = false;
|
m_IsTeleporting = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2599,16 +2704,19 @@ float cPlayer::GetLiquidHeightPercent(NIBBLETYPE a_Meta)
|
|||||||
|
|
||||||
bool cPlayer::IsInsideWater()
|
bool cPlayer::IsInsideWater()
|
||||||
{
|
{
|
||||||
BLOCKTYPE Block = m_World->GetBlock(Vector3d(GetPosX(), m_Stance, GetPosZ()).Floor());
|
BLOCKTYPE Block;
|
||||||
|
NIBBLETYPE Meta;
|
||||||
|
m_World->GetBlockTypeMeta(GetEyePosition().Floor(), Block, Meta);
|
||||||
|
|
||||||
if ((Block != E_BLOCK_WATER) && (Block != E_BLOCK_STATIONARY_WATER))
|
if ((Block != E_BLOCK_WATER) && (Block != E_BLOCK_STATIONARY_WATER))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
NIBBLETYPE Meta = GetWorld()->GetBlockMeta(Vector3d(GetPosX(), m_Stance, GetPosZ()).Floor());
|
|
||||||
|
const auto EyeHeight = GetEyeHeight();
|
||||||
float f = GetLiquidHeightPercent(Meta) - 0.11111111f;
|
float f = GetLiquidHeightPercent(Meta) - 0.11111111f;
|
||||||
float f1 = static_cast<float>(m_Stance + 1) - f;
|
float f1 = static_cast<float>(EyeHeight + 1) - f;
|
||||||
bool flag = (m_Stance < f1);
|
return EyeHeight < f1;
|
||||||
return flag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2742,6 +2850,16 @@ void cPlayer::AddKnownItem(const cItem & a_Item)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cPlayer::SetSize(const float a_Width, const float a_Height)
|
||||||
|
{
|
||||||
|
m_Width = a_Width;
|
||||||
|
m_Height = a_Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::AddKnownRecipe(UInt32 a_RecipeId)
|
void cPlayer::AddKnownRecipe(UInt32 a_RecipeId)
|
||||||
{
|
{
|
||||||
auto Response = m_KnownRecipes.insert(a_RecipeId);
|
auto Response = m_KnownRecipes.insert(a_RecipeId);
|
||||||
@ -2916,6 +3034,33 @@ float cPlayer::GetEnchantmentBlastKnockbackReduction()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cPlayer::IsCrouched(void) const
|
||||||
|
{
|
||||||
|
return std::holds_alternative<BodyStanceCrouching>(m_BodyStance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cPlayer::IsElytraFlying(void) const
|
||||||
|
{
|
||||||
|
return std::holds_alternative<BodyStanceGliding>(m_BodyStance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cPlayer::IsSprinting(void) const
|
||||||
|
{
|
||||||
|
return std::holds_alternative<BodyStanceSprinting>(m_BodyStance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cPlayer::OnAddToWorld(cWorld & a_World)
|
void cPlayer::OnAddToWorld(cWorld & a_World)
|
||||||
{
|
{
|
||||||
Super::OnAddToWorld(a_World);
|
Super::OnAddToWorld(a_World);
|
||||||
@ -3023,7 +3168,7 @@ void cPlayer::OnRemoveFromWorld(cWorld & a_World)
|
|||||||
|
|
||||||
void cPlayer::SpawnOn(cClientHandle & a_Client)
|
void cPlayer::SpawnOn(cClientHandle & a_Client)
|
||||||
{
|
{
|
||||||
if (!m_bVisible || (m_ClientHandle.get() == (&a_Client)))
|
if (!m_IsVisible || (m_ClientHandle.get() == (&a_Client)))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3110,6 +3255,27 @@ void cPlayer::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
|||||||
m_BowCharge += 1;
|
m_BowCharge += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsElytraFlying())
|
||||||
|
{
|
||||||
|
// Damage elytra, once per second:
|
||||||
|
{
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
auto & TicksFlying = std::get<BodyStanceGliding>(m_BodyStance).TicksElytraFlying;
|
||||||
|
const auto TotalFlew = TicksFlying + a_Dt;
|
||||||
|
const auto Periods = static_cast<short>(TotalFlew / 1s);
|
||||||
|
TicksFlying = std::chrono::duration_cast<cTickTime>(TotalFlew - Periods * 1s);
|
||||||
|
|
||||||
|
UseItem(cInventory::invArmorOffset + 1, Periods);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if flight is still possible:
|
||||||
|
if (IsOnGround() || IsInWater() || IsRiding() || (GetEquippedChestplate().m_ItemType != E_ITEM_ELYTRA))
|
||||||
|
{
|
||||||
|
SetElytraFlight(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BroadcastMovementUpdate(m_ClientHandle.get());
|
BroadcastMovementUpdate(m_ClientHandle.get());
|
||||||
|
|
||||||
if (m_Health > 0) // make sure player is alive
|
if (m_Health > 0) // make sure player is alive
|
||||||
|
@ -27,11 +27,57 @@ class cTeam;
|
|||||||
class cPlayer:
|
class cPlayer:
|
||||||
public cPawn
|
public cPawn
|
||||||
{
|
{
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
using Super = cPawn;
|
using Super = cPawn;
|
||||||
|
|
||||||
|
/** Tag representing a sneaking pose. */
|
||||||
|
struct BodyStanceCrouching
|
||||||
|
{
|
||||||
|
BodyStanceCrouching(cPlayer & a_Player);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Tag representing a sleeping pose.
|
||||||
|
Set by a right click on unoccupied bed, unset by a time fast forward or teleport. */
|
||||||
|
struct BodyStanceSleeping
|
||||||
|
{
|
||||||
|
BodyStanceSleeping(cPlayer & a_Player);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Tag representing a sprinting pose. */
|
||||||
|
struct BodyStanceSprinting
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Tag representing the neutral stance. */
|
||||||
|
struct BodyStanceStanding
|
||||||
|
{
|
||||||
|
BodyStanceStanding(cPlayer & a_Player);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Tag representing a swimming or elytra flying pose. */
|
||||||
|
struct BodyStanceGliding
|
||||||
|
{
|
||||||
|
BodyStanceGliding(cPlayer & a_Player);
|
||||||
|
|
||||||
|
cTickTime TicksElytraFlying;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct HandStanceNeutral
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HandStandChargingBow
|
||||||
|
{
|
||||||
|
int m_BowCharge;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct HandStanceEating
|
||||||
|
{
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -105,11 +151,8 @@ public:
|
|||||||
bool IsChargingBow(void) const { return m_IsChargingBow; }
|
bool IsChargingBow(void) const { return m_IsChargingBow; }
|
||||||
|
|
||||||
void SetTouchGround(bool a_bTouchGround);
|
void SetTouchGround(bool a_bTouchGround);
|
||||||
inline void SetStance(const double a_Stance) { m_Stance = a_Stance; }
|
|
||||||
double GetEyeHeight(void) const; // tolua_export
|
double GetEyeHeight(void) const; // tolua_export
|
||||||
Vector3d GetEyePosition(void) const; // tolua_export
|
Vector3d GetEyePosition(void) const; // tolua_export
|
||||||
virtual bool IsOnGround(void) const override { return m_bTouchGround; }
|
|
||||||
inline double GetStance(void) const { return m_Stance; } // tolua_export
|
|
||||||
inline cInventory & GetInventory(void) { return m_Inventory; } // tolua_export
|
inline cInventory & GetInventory(void) { return m_Inventory; } // tolua_export
|
||||||
inline const cInventory & GetInventory(void) const { return m_Inventory; }
|
inline const cInventory & GetInventory(void) const { return m_Inventory; }
|
||||||
|
|
||||||
@ -333,8 +376,8 @@ public:
|
|||||||
/** Returns true if the player is currently flying */
|
/** Returns true if the player is currently flying */
|
||||||
bool IsFlying(void) const { return m_IsFlying; }
|
bool IsFlying(void) const { return m_IsFlying; }
|
||||||
|
|
||||||
/** Returns true if a player is sleeping in a bed */
|
/** Returns true if a player is sleeping in a bed. */
|
||||||
bool IsInBed(void) const { return m_bIsInBed; }
|
bool IsInBed(void) const;
|
||||||
|
|
||||||
/** Returns true if the player has thrown out a floater */
|
/** Returns true if the player has thrown out a floater */
|
||||||
bool IsFishing(void) const { return m_IsFishing; }
|
bool IsFishing(void) const { return m_IsFishing; }
|
||||||
@ -345,21 +388,16 @@ public:
|
|||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
|
/** Returns true if a player is standing normally, that is, in a neutral pose. */
|
||||||
|
bool IsStanding() const;
|
||||||
|
|
||||||
/** Tosses a list of items. */
|
/** Tosses a list of items. */
|
||||||
void TossItems(const cItems & a_Items);
|
void TossItems(const cItems & a_Items);
|
||||||
|
|
||||||
/** Sets a player's in-bed state
|
/** Sets a player's in-bed state.
|
||||||
We can't be sure plugins will keep this value updated, so no exporting
|
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
|
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_IsInBed);
|
||||||
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);
|
||||||
@ -377,7 +415,7 @@ public:
|
|||||||
void Respawn(void); // tolua_export
|
void Respawn(void); // tolua_export
|
||||||
|
|
||||||
void SetVisible( bool a_bVisible); // tolua_export
|
void SetVisible( bool a_bVisible); // tolua_export
|
||||||
bool IsVisible(void) const { return m_bVisible; } // tolua_export
|
bool IsVisible(void) const { return m_IsVisible; } // tolua_export
|
||||||
|
|
||||||
/** Saves all player data, such as inventory, to JSON. */
|
/** Saves all player data, such as inventory, to JSON. */
|
||||||
void SaveToDisk(void);
|
void SaveToDisk(void);
|
||||||
@ -450,14 +488,17 @@ public:
|
|||||||
/** Sets the flying relative maximum speed. Sends the update to player, if needed. */
|
/** Sets the flying relative maximum speed. Sends the update to player, if needed. */
|
||||||
void SetFlyingMaxSpeed(double a_Speed);
|
void SetFlyingMaxSpeed(double a_Speed);
|
||||||
|
|
||||||
/** Sets the crouch status, broadcasts to all visible players */
|
/** Starts or stops crouching, if our current body stance permits, broadcasting the state change. */
|
||||||
void SetCrouch(bool a_IsCrouched);
|
void SetCrouch(bool a_ShouldCrouch);
|
||||||
|
|
||||||
/** Starts or stops sprinting, sends the max speed update to the client, if needed */
|
/** Starts or stops elytra flight, if our current body stance permits, broadcasting the state change. */
|
||||||
void SetSprint(bool a_IsSprinting);
|
void SetElytraFlight(bool a_ShouldElytraFly);
|
||||||
|
|
||||||
/** Flags the player as flying */
|
/** Starts or stops flying, broadcasting the state change. */
|
||||||
void SetFlying(bool a_IsFlying);
|
void SetFlying(bool a_ShouldFly);
|
||||||
|
|
||||||
|
/** Starts or stops sprinting, if our current body stance permits, broadcasting the state change. */
|
||||||
|
void SetSprint(bool a_ShouldSprint);
|
||||||
|
|
||||||
/** If true the player can fly even when he's not in creative. */
|
/** If true the player can fly even when he's not in creative. */
|
||||||
void SetCanFly(bool a_CanFly);
|
void SetCanFly(bool a_CanFly);
|
||||||
@ -501,7 +542,7 @@ public:
|
|||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
/** Returns wheter the player can fly or not. */
|
/** Returns wheter the player can fly or not. */
|
||||||
virtual bool CanFly(void) const { return m_CanFly; }
|
virtual bool CanFly(void) const { return m_IsFlightCapable; }
|
||||||
|
|
||||||
/** (Re)loads the rank and permissions from the cRankManager.
|
/** (Re)loads the rank and permissions from the cRankManager.
|
||||||
Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */
|
Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */
|
||||||
@ -541,14 +582,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved);
|
void NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved);
|
||||||
|
|
||||||
// cEntity overrides:
|
|
||||||
virtual bool IsCrouched (void) const override { return m_IsCrouched; }
|
|
||||||
virtual bool IsSprinting(void) const override { return m_IsSprinting; }
|
|
||||||
virtual bool IsRclking (void) const override { return IsEating() || IsChargingBow(); }
|
|
||||||
|
|
||||||
virtual void AttachTo(cEntity * a_AttachTo) override;
|
|
||||||
virtual void Detach(void) override;
|
|
||||||
|
|
||||||
/** Returns the progress mined per tick for the block a_Block as a fraction
|
/** Returns the progress mined per tick for the block a_Block as a fraction
|
||||||
(1 would be completely mined)
|
(1 would be completely mined)
|
||||||
Depends on hardness values so check those are correct.
|
Depends on hardness values so check those are correct.
|
||||||
@ -565,18 +598,38 @@ public:
|
|||||||
If the item is already known, does nothing. */
|
If the item is already known, does nothing. */
|
||||||
void AddKnownItem(const cItem & a_Item);
|
void AddKnownItem(const cItem & a_Item);
|
||||||
|
|
||||||
|
/** Update a player's size, for example, on body stance changes. */
|
||||||
|
void SetSize(float a_Width, float a_Height);
|
||||||
|
|
||||||
// cEntity overrides:
|
// cEntity overrides:
|
||||||
|
virtual void AttachTo(cEntity * a_AttachTo) override;
|
||||||
|
virtual void Detach(void) override;
|
||||||
virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); }
|
virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); }
|
||||||
virtual cItem GetEquippedHelmet(void) const override { return m_Inventory.GetEquippedHelmet(); }
|
virtual cItem GetEquippedHelmet(void) const override { return m_Inventory.GetEquippedHelmet(); }
|
||||||
virtual cItem GetEquippedChestplate(void) const override { return m_Inventory.GetEquippedChestplate(); }
|
virtual cItem GetEquippedChestplate(void) const override { return m_Inventory.GetEquippedChestplate(); }
|
||||||
virtual cItem GetEquippedLeggings(void) const override { return m_Inventory.GetEquippedLeggings(); }
|
virtual cItem GetEquippedLeggings(void) const override { return m_Inventory.GetEquippedLeggings(); }
|
||||||
virtual cItem GetEquippedBoots(void) const override { return m_Inventory.GetEquippedBoots(); }
|
virtual cItem GetEquippedBoots(void) const override { return m_Inventory.GetEquippedBoots(); }
|
||||||
virtual cItem GetOffHandEquipedItem(void) const override { return m_Inventory.GetShieldSlot(); }
|
virtual cItem GetOffHandEquipedItem(void) const override { return m_Inventory.GetShieldSlot(); }
|
||||||
|
virtual bool IsCrouched(void) const override;
|
||||||
|
virtual bool IsElytraFlying(void) const override;
|
||||||
|
virtual bool IsOnGround(void) const override { return m_bTouchGround; }
|
||||||
|
virtual bool IsSprinting(void) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/** Xp Level stuff */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
XP_TO_LEVEL15 = 255,
|
||||||
|
XP_PER_LEVEL_TO15 = 17,
|
||||||
|
XP_TO_LEVEL30 = 825
|
||||||
|
} ;
|
||||||
|
|
||||||
typedef std::vector<std::vector<AString> > AStringVectorVector;
|
typedef std::vector<std::vector<AString> > AStringVectorVector;
|
||||||
|
|
||||||
|
/** The current body stance the player has adopted. */
|
||||||
|
std::variant<BodyStanceCrouching, BodyStanceSleeping, BodyStanceSprinting, BodyStanceStanding, BodyStanceGliding> m_BodyStance;
|
||||||
|
|
||||||
/** The name of the rank assigned to this player. */
|
/** The name of the rank assigned to this player. */
|
||||||
AString m_Rank;
|
AString m_Rank;
|
||||||
|
|
||||||
@ -599,16 +652,6 @@ private:
|
|||||||
AString m_MsgPrefix, m_MsgSuffix;
|
AString m_MsgPrefix, m_MsgSuffix;
|
||||||
AString m_MsgNameColorCode;
|
AString m_MsgNameColorCode;
|
||||||
|
|
||||||
/** Xp Level stuff */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
XP_TO_LEVEL15 = 255,
|
|
||||||
XP_PER_LEVEL_TO15 = 17,
|
|
||||||
XP_TO_LEVEL30 = 825
|
|
||||||
} ;
|
|
||||||
|
|
||||||
bool m_bVisible;
|
|
||||||
|
|
||||||
// Food-related variables:
|
// Food-related variables:
|
||||||
/** Represents the food bar, one point equals half a "drumstick" */
|
/** Represents the food bar, one point equals half a "drumstick" */
|
||||||
int m_FoodLevel;
|
int m_FoodLevel;
|
||||||
@ -622,8 +665,6 @@ private:
|
|||||||
/** A "buffer" which adds up hunger before it is substracted from m_FoodSaturationLevel or m_FoodLevel. Each action adds a little */
|
/** A "buffer" which adds up hunger before it is substracted from m_FoodSaturationLevel or m_FoodLevel. Each action adds a little */
|
||||||
double m_FoodExhaustionLevel;
|
double m_FoodExhaustionLevel;
|
||||||
|
|
||||||
double m_Stance;
|
|
||||||
|
|
||||||
/** Stores the player's inventory, consisting of crafting grid, hotbar, and main slots */
|
/** Stores the player's inventory, consisting of crafting grid, hotbar, and main slots */
|
||||||
cInventory m_Inventory;
|
cInventory m_Inventory;
|
||||||
|
|
||||||
@ -656,12 +697,6 @@ private:
|
|||||||
|
|
||||||
cSlotNums m_InventoryPaintSlots;
|
cSlotNums m_InventoryPaintSlots;
|
||||||
|
|
||||||
/** If true, we are locking m_Position to m_FrozenPosition. */
|
|
||||||
bool m_IsFrozen;
|
|
||||||
|
|
||||||
/** Was the player frozen manually by a plugin or automatically by the server? */
|
|
||||||
bool m_IsManuallyFrozen;
|
|
||||||
|
|
||||||
/** Max speed, relative to the game default.
|
/** Max speed, relative to the game default.
|
||||||
1 means regular speed, 2 means twice as fast, 0.5 means half-speed.
|
1 means regular speed, 2 means twice as fast, 0.5 means half-speed.
|
||||||
Default value is 1. */
|
Default value is 1. */
|
||||||
@ -677,12 +712,25 @@ private:
|
|||||||
Default value is 1. */
|
Default value is 1. */
|
||||||
double m_FlyingMaxSpeed;
|
double m_FlyingMaxSpeed;
|
||||||
|
|
||||||
bool m_IsCrouched;
|
bool m_IsChargingBow;
|
||||||
bool m_IsSprinting;
|
|
||||||
bool m_IsFlying;
|
|
||||||
bool m_IsFishing;
|
bool m_IsFishing;
|
||||||
|
|
||||||
bool m_CanFly; // If this is true the player can fly. Even if he is not in creative.
|
/** If this is true the player can fly. Even if he is not in creative. */
|
||||||
|
bool m_IsFlightCapable;
|
||||||
|
|
||||||
|
bool m_IsFlying;
|
||||||
|
|
||||||
|
/** If true, we are locking m_Position to m_FrozenPosition. */
|
||||||
|
bool m_IsFrozen;
|
||||||
|
|
||||||
|
/** Was the player frozen manually by a plugin or automatically by the server? */
|
||||||
|
bool m_IsManuallyFrozen;
|
||||||
|
|
||||||
|
/** Flag used by food handling system to determine whether a teleport has just happened.
|
||||||
|
Will not apply food penalties if found to be true; will set to false after processing. */
|
||||||
|
bool m_IsTeleporting;
|
||||||
|
|
||||||
|
bool m_IsVisible;
|
||||||
|
|
||||||
/** The world tick in which eating will be finished. -1 if not eating */
|
/** The world tick in which eating will be finished. -1 if not eating */
|
||||||
Int64 m_EatingFinishTick;
|
Int64 m_EatingFinishTick;
|
||||||
@ -692,8 +740,7 @@ private:
|
|||||||
int m_CurrentXp;
|
int m_CurrentXp;
|
||||||
unsigned int m_EnchantmentSeed;
|
unsigned int m_EnchantmentSeed;
|
||||||
|
|
||||||
bool m_IsChargingBow;
|
int m_BowCharge;
|
||||||
int m_BowCharge;
|
|
||||||
|
|
||||||
UInt32 m_FloaterID;
|
UInt32 m_FloaterID;
|
||||||
|
|
||||||
@ -701,19 +748,10 @@ private:
|
|||||||
|
|
||||||
cStatManager m_Stats;
|
cStatManager m_Stats;
|
||||||
|
|
||||||
/** Flag representing whether the player is currently in a bed
|
|
||||||
Set by a right click on unoccupied bed, unset by a time fast forward or teleport */
|
|
||||||
bool m_bIsInBed;
|
|
||||||
|
|
||||||
/** How long till the player's inventory will be saved
|
/** How long till the player's inventory will be saved
|
||||||
Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */
|
Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */
|
||||||
unsigned int m_TicksUntilNextSave;
|
unsigned int m_TicksUntilNextSave;
|
||||||
|
|
||||||
/** Flag used by food handling system to determine whether a teleport has just happened
|
|
||||||
Will not apply food penalties if found to be true; will set to false after processing
|
|
||||||
*/
|
|
||||||
bool m_bIsTeleporting;
|
|
||||||
|
|
||||||
AString m_CustomName;
|
AString m_CustomName;
|
||||||
|
|
||||||
/** Displayed skin part bit mask */
|
/** Displayed skin part bit mask */
|
||||||
@ -769,6 +807,7 @@ private:
|
|||||||
virtual bool DoTakeDamage(TakeDamageInfo & TDI) override;
|
virtual bool DoTakeDamage(TakeDamageInfo & TDI) override;
|
||||||
virtual float GetEnchantmentBlastKnockbackReduction() override;
|
virtual float GetEnchantmentBlastKnockbackReduction() override;
|
||||||
virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk &) override { UNUSED(a_Dt); }
|
virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk &) override { UNUSED(a_Dt); }
|
||||||
|
virtual bool IsRclking(void) const override { return IsEating() || IsChargingBow(); }
|
||||||
virtual void OnAddToWorld(cWorld & a_World) override;
|
virtual void OnAddToWorld(cWorld & a_World) override;
|
||||||
virtual void OnRemoveFromWorld(cWorld & a_World) override;
|
virtual void OnRemoveFromWorld(cWorld & a_World) override;
|
||||||
virtual void SpawnOn(cClientHandle & a_Client) override;
|
virtual void SpawnOn(cClientHandle & a_Client) override;
|
||||||
|
@ -133,6 +133,7 @@ short cItem::GetMaxDamage(void) const
|
|||||||
case E_ITEM_DIAMOND_PICKAXE: return 1561;
|
case E_ITEM_DIAMOND_PICKAXE: return 1561;
|
||||||
case E_ITEM_DIAMOND_SHOVEL: return 1561;
|
case E_ITEM_DIAMOND_SHOVEL: return 1561;
|
||||||
case E_ITEM_DIAMOND_SWORD: return 1561;
|
case E_ITEM_DIAMOND_SWORD: return 1561;
|
||||||
|
case E_ITEM_ELYTRA: return 432;
|
||||||
case E_ITEM_FLINT_AND_STEEL: return 64;
|
case E_ITEM_FLINT_AND_STEEL: return 64;
|
||||||
case E_ITEM_FISHING_ROD: return 65;
|
case E_ITEM_FISHING_ROD: return 65;
|
||||||
case E_ITEM_GOLD_AXE: return 32;
|
case E_ITEM_GOLD_AXE: return 32;
|
||||||
|
@ -63,14 +63,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
a_Player->GetInventory().SetArmorSlot(SlotNum, a_HeldItem.CopyOne());
|
a_Player->GetInventory().SetArmorSlot(SlotNum, a_HeldItem.CopyOne());
|
||||||
|
a_Player->GetInventory().RemoveOneEquippedItem();
|
||||||
cItem Item(a_HeldItem);
|
|
||||||
Item.m_ItemCount--;
|
|
||||||
if (Item.m_ItemCount <= 0)
|
|
||||||
{
|
|
||||||
Item.Empty();
|
|
||||||
}
|
|
||||||
a_Player->GetInventory().SetEquippedItem(Item);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +103,7 @@ public:
|
|||||||
{
|
{
|
||||||
return (a_ItemType == E_ITEM_GOLD);
|
return (a_ItemType == E_ITEM_GOLD);
|
||||||
}
|
}
|
||||||
|
case E_ITEM_ELYTRA: // TODO: require Phantom Membrane instead of leather starting from protocol version 369 or 1.13 release
|
||||||
case E_ITEM_LEATHER_BOOTS:
|
case E_ITEM_LEATHER_BOOTS:
|
||||||
case E_ITEM_LEATHER_CAP:
|
case E_ITEM_LEATHER_CAP:
|
||||||
case E_ITEM_LEATHER_PANTS:
|
case E_ITEM_LEATHER_PANTS:
|
||||||
|
@ -282,6 +282,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType)
|
|||||||
case E_ITEM_RABBIT_STEW: return new cItemSoupHandler(a_ItemType, FoodInfo(10, 12));
|
case E_ITEM_RABBIT_STEW: return new cItemSoupHandler(a_ItemType, FoodInfo(10, 12));
|
||||||
|
|
||||||
// Armor:
|
// Armor:
|
||||||
|
case E_ITEM_ELYTRA:
|
||||||
case E_ITEM_LEATHER_CAP:
|
case E_ITEM_LEATHER_CAP:
|
||||||
case E_ITEM_GOLD_HELMET:
|
case E_ITEM_GOLD_HELMET:
|
||||||
case E_ITEM_CHAIN_HELMET:
|
case E_ITEM_CHAIN_HELMET:
|
||||||
|
@ -349,6 +349,10 @@ void cProtocol_1_12::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_
|
|||||||
{
|
{
|
||||||
Flags |= 0x20;
|
Flags |= 0x20;
|
||||||
}
|
}
|
||||||
|
if (a_Entity.IsElytraFlying())
|
||||||
|
{
|
||||||
|
Flags |= 0x80;
|
||||||
|
}
|
||||||
a_Pkt.WriteBEUInt8(ENTITY_FLAGS); // Index
|
a_Pkt.WriteBEUInt8(ENTITY_FLAGS); // Index
|
||||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); // Type
|
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); // Type
|
||||||
a_Pkt.WriteBEInt8(Flags);
|
a_Pkt.WriteBEInt8(Flags);
|
||||||
|
@ -2462,14 +2462,20 @@ void cProtocol_1_8_0::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer)
|
|||||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Action);
|
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Action);
|
||||||
HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost);
|
HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost);
|
||||||
|
|
||||||
|
if (PlayerID != m_Client->GetPlayer()->GetUniqueID())
|
||||||
|
{
|
||||||
|
m_Client->Kick("Mind your own business! Hacked client?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (Action)
|
switch (Action)
|
||||||
{
|
{
|
||||||
case 0: m_Client->HandleEntityCrouch(PlayerID, true); break; // Crouch
|
case 0: return m_Client->HandleCrouch(true);
|
||||||
case 1: m_Client->HandleEntityCrouch(PlayerID, false); break; // Uncrouch
|
case 1: return m_Client->HandleCrouch(false);
|
||||||
case 2: m_Client->HandleEntityLeaveBed(PlayerID); break; // Leave Bed
|
case 2: return m_Client->HandleLeaveBed();
|
||||||
case 3: m_Client->HandleEntitySprinting(PlayerID, true); break; // Start sprinting
|
case 3: return m_Client->HandleSprint(true);
|
||||||
case 4: m_Client->HandleEntitySprinting(PlayerID, false); break; // Stop sprinting
|
case 4: return m_Client->HandleSprint(false);
|
||||||
case 6: m_Client->HandleOpenHorseInventory(PlayerID); break; // Open horse inventory
|
case 6: return m_Client->HandleOpenHorseInventory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2535,7 +2541,7 @@ void cProtocol_1_8_0::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
|
|||||||
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
|
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
|
||||||
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
|
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
|
||||||
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
|
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
|
||||||
m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + (m_Client->GetPlayer()->IsCrouched() ? 1.54 : 1.62), IsOnGround);
|
m_Client->HandlePlayerPos(PosX, PosY, PosZ, IsOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2550,7 +2556,7 @@ void cProtocol_1_8_0::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
|
|||||||
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw);
|
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw);
|
||||||
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
|
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
|
||||||
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
|
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
|
||||||
m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, PosY + 1.62, Yaw, Pitch, IsOnGround);
|
m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Yaw, Pitch, IsOnGround);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3355,6 +3361,10 @@ void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a
|
|||||||
{
|
{
|
||||||
Flags |= 0x20;
|
Flags |= 0x20;
|
||||||
}
|
}
|
||||||
|
if (a_Entity.IsElytraFlying())
|
||||||
|
{
|
||||||
|
Flags |= 0x80;
|
||||||
|
}
|
||||||
a_Pkt.WriteBEUInt8(0); // Byte(0) + index 0
|
a_Pkt.WriteBEUInt8(0); // Byte(0) + index 0
|
||||||
a_Pkt.WriteBEUInt8(Flags);
|
a_Pkt.WriteBEUInt8(Flags);
|
||||||
|
|
||||||
|
@ -945,14 +945,21 @@ void cProtocol_1_9_0::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer)
|
|||||||
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Action);
|
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Action);
|
||||||
HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost);
|
HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost);
|
||||||
|
|
||||||
|
if (PlayerID != m_Client->GetPlayer()->GetUniqueID())
|
||||||
|
{
|
||||||
|
m_Client->Kick("Mind your own business! Hacked client?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (Action)
|
switch (Action)
|
||||||
{
|
{
|
||||||
case 0: m_Client->HandleEntityCrouch(PlayerID, true); break; // Crouch
|
case 0: return m_Client->HandleCrouch(true);
|
||||||
case 1: m_Client->HandleEntityCrouch(PlayerID, false); break; // Uncrouch
|
case 1: return m_Client->HandleCrouch(false);
|
||||||
case 2: m_Client->HandleEntityLeaveBed(PlayerID); break; // Leave Bed
|
case 2: return m_Client->HandleLeaveBed();
|
||||||
case 3: m_Client->HandleEntitySprinting(PlayerID, true); break; // Start sprinting
|
case 3: return m_Client->HandleSprint(true);
|
||||||
case 4: m_Client->HandleEntitySprinting(PlayerID, false); break; // Stop sprinting
|
case 4: return m_Client->HandleSprint(false);
|
||||||
case 7: m_Client->HandleOpenHorseInventory(PlayerID); break; // Open horse inventory
|
case 7: return m_Client->HandleOpenHorseInventory();
|
||||||
|
case 8: return m_Client->HandleStartElytraFlight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -969,7 +976,7 @@ void cProtocol_1_9_0::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
|
|||||||
|
|
||||||
if (m_IsTeleportIdConfirmed)
|
if (m_IsTeleportIdConfirmed)
|
||||||
{
|
{
|
||||||
m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + (m_Client->GetPlayer()->IsCrouched() ? 1.54 : 1.62), IsOnGround);
|
m_Client->HandlePlayerPos(PosX, PosY, PosZ, IsOnGround);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -988,7 +995,7 @@ void cProtocol_1_9_0::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
|
|||||||
|
|
||||||
if (m_IsTeleportIdConfirmed)
|
if (m_IsTeleportIdConfirmed)
|
||||||
{
|
{
|
||||||
m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, PosY + 1.62, Yaw, Pitch, IsOnGround);
|
m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Yaw, Pitch, IsOnGround);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1666,6 +1673,10 @@ void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a
|
|||||||
{
|
{
|
||||||
Flags |= 0x20;
|
Flags |= 0x20;
|
||||||
}
|
}
|
||||||
|
if (a_Entity.IsElytraFlying())
|
||||||
|
{
|
||||||
|
Flags |= 0x80;
|
||||||
|
}
|
||||||
a_Pkt.WriteBEUInt8(0); // Index 0
|
a_Pkt.WriteBEUInt8(0); // Index 0
|
||||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); // Type
|
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); // Type
|
||||||
a_Pkt.WriteBEInt8(Flags);
|
a_Pkt.WriteBEInt8(Flags);
|
||||||
|
@ -33,16 +33,7 @@ class cPlayer;
|
|||||||
class cClientHandle;
|
class cClientHandle;
|
||||||
class cEntity;
|
class cEntity;
|
||||||
class cChunkGenerator; // The thread responsible for generating chunks
|
class cChunkGenerator; // The thread responsible for generating chunks
|
||||||
class cBeaconEntity;
|
|
||||||
class cBrewingstandEntity;
|
|
||||||
class cChestEntity;
|
|
||||||
class cCuboid;
|
class cCuboid;
|
||||||
class cDispenserEntity;
|
|
||||||
class cFlowerPotEntity;
|
|
||||||
class cFurnaceEntity;
|
|
||||||
class cHopperEntity;
|
|
||||||
class cNoteEntity;
|
|
||||||
class cMobHeadEntity;
|
|
||||||
class cCompositeChat;
|
class cCompositeChat;
|
||||||
class cDeadlockDetect;
|
class cDeadlockDetect;
|
||||||
class cUUID;
|
class cUUID;
|
||||||
|
Loading…
Reference in New Issue
Block a user