summaryrefslogtreecommitdiffstats
path: root/src/Entities/Player.h
blob: 8969099a16ff6bf338bb8e77e62ceada43a1ea56 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809

#pragma once

#include "Pawn.h"
#include "../Inventory.h"
#include "../Defines.h"
#include "../World.h"
#include "../Items/ItemHandler.h"

#include "../Statistics.h"

#include "../UUID.h"





class cWindow;
class cClientHandle;
class cTeam;





// tolua_begin
class cPlayer:
	public cPawn
{
	// tolua_end

	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

public:

	static const int MAX_HEALTH;

	static const int MAX_FOOD_LEVEL;

	// tolua_end

	CLASS_PROTODEF(cPlayer)

	cPlayer(const std::shared_ptr<cClientHandle> & a_Client);
	virtual ~cPlayer() override;

	// tolua_begin

	/** Sets the experience total
	Returns true on success
	"should" really only be called at init or player death, plugins excepted
	*/
	bool SetCurrentExperience(int a_XpTotal);

	/* changes Xp by Xp_delta, you "shouldn't" inc more than MAX_EXPERIENCE_ORB_SIZE
	Wont't allow xp to go negative
	Returns the new current experience, -1 on error
	*/
	int DeltaExperience(int a_Xp_delta);

	/** Gets the experience total - XpTotal for score on death */
	inline int GetXpLifetimeTotal(void) { return m_LifetimeTotalXp; }

	/** Gets the current experience */
	inline int GetCurrentXp(void) { return m_CurrentXp; }

	/** Gets the current level - XpLevel */
	int GetXpLevel(void) const;

	/** Gets the experience bar percentage - XpP */
	float GetXpPercentage(void) const;

	/** Calculates the amount of XP needed for a given level
	Ref: https://minecraft.gamepedia.com/XP
	*/
	static int XpForLevel(int a_Level);

	/** Inverse of XpForLevel
	Ref: https://minecraft.gamepedia.com/XP
	values are as per this with pre-calculations
	*/
	static int CalcLevelFromXp(int a_CurrentXp);

	// tolua_end

	/** Gets the set of IDs for recipes this player has discovered. */
	const std::set<UInt32> & GetKnownRecipes() const;

	/** Starts charging the equipped bow */
	void StartChargingBow(void);

	/** Finishes charging the current bow. Returns the number of ticks for which the bow has been charged */
	int FinishChargingBow(void);

	/** Cancels the current bow charging */
	void CancelChargingBow(void);

	/** Returns true if the player is currently charging the bow */
	bool IsChargingBow(void) const { return m_IsChargingBow; }

	void SetTouchGround(bool a_bTouchGround);
	double GetEyeHeight(void) const;  // tolua_export
	Vector3d GetEyePosition(void) const;  // tolua_export
	inline cInventory &       GetInventory(void)       { return m_Inventory; }  // tolua_export
	inline const cInventory & GetInventory(void) const { return m_Inventory; }

	/** Gets the contents of the player's associated enderchest */
	cItemGrid & GetEnderChestContents(void) { return m_EnderChestContents; }

	inline const cItem & GetEquippedItem(void) const { return GetInventory().GetEquippedItem(); }  // tolua_export

	/** Returns whether the player is climbing (ladders, vines etc.) */
	bool IsClimbing(void) const;

	virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ) override;

	/** Updates player's capabilities - flying, visibility, etc. from their gamemode. */
	void UpdateCapabilities();

	// tolua_begin

	/** Prevent the player from moving and lock him into a_Location. */
	void Freeze(const Vector3d & a_Location);

	/** Is the player frozen? */
	bool IsFrozen();

	/** Cancels Freeze(...) and allows the player to move naturally. */
	void Unfreeze();

	/** Sends the "look" packet to the player, forcing them to set their rotation to the specified values.
	a_YawDegrees is clipped to range [-180, +180),
	a_PitchDegrees is clipped to range [-180, +180) but the client only uses [-90, +90]
	*/
	void SendRotation(double a_YawDegrees, double a_PitchDegrees);

	/** Spectates the target entity. If a_Target is nullptr or a pointer to self, end spectation. */
	void SpectateEntity(cEntity * a_Target);

	/** Returns the position where projectiles thrown by this player should start, player eye position + adjustment */
	Vector3d GetThrowStartPos(void) const;

	/** Returns the initial speed vector of a throw, with a 3D length of a_SpeedCoeff. */
	Vector3d GetThrowSpeed(double a_SpeedCoeff) const;

	/** Returns the current gamemode. Partly OBSOLETE, you should use IsGameModeXXX() functions wherever applicable */
	eGameMode GetGameMode(void) const { return m_GameMode; }

	/** Returns the current effective gamemode (inherited gamemode is resolved before returning) */
	eGameMode GetEffectiveGameMode(void) const;

	/** Sets the gamemode for the player.
	The gamemode may be gmNotSet, in that case the player inherits the world's gamemode.
	Updates the gamemode on the client (sends the packet)
	*/
	void SetGameMode(eGameMode a_GameMode);

	/** Returns true if the player is in Creative mode, either explicitly, or by inheriting from current world */
	bool IsGameModeCreative(void) const;

	/** Returns true if the player is in Survival mode, either explicitly, or by inheriting from current world */
	bool IsGameModeSurvival(void) const;

	/** Returns true if the player is in Adventure mode, either explicitly, or by inheriting from current world */
	bool IsGameModeAdventure(void) const;

	/** Returns true if the player is in Spectator mode, either explicitly, or by inheriting from current world */
	bool IsGameModeSpectator(void) const;

	/** Returns true if the player is fireproof
	Stops players burning in creative or spectator modes.
	*/
	virtual bool IsFireproof() const override
	{
		return (m_IsFireproof || IsGameModeCreative() || IsGameModeSpectator());

	}

	/** Returns true if the player can be targeted by Mobs */
	bool CanMobsTarget(void) const;

	AString GetIP(void) const;  // tolua_export

	/** Returns the associated team, nullptr if none */
	cTeam * GetTeam(void) { return m_Team; }  // tolua_export

	/** Returns the associated team, nullptr if none */
	const cTeam * GetTeam(void) const { return m_Team; }

	/** Sets the player team, nullptr if none */
	void SetTeam(cTeam * a_Team);

	// tolua_end

	/** Forces the player to query the scoreboard for his team */
	cTeam * UpdateTeam(void);

	/** Return the associated statistic and achievement manager. */
	cStatManager & GetStatManager() { return m_Stats; }

	/** Awards the player an achievement.
	If all prerequisites are met, this method will award the achievement and will broadcast a chat message.
	If the achievement has been already awarded to the player, this method will just increment the stat counter. */
	void AwardAchievement(Statistic a_Ach);

	/** Forces the player to move in the given direction.
	@deprecated Use SetSpeed instead. */
	void ForceSetSpeed(const Vector3d & a_Speed);  // tolua_export

	cWindow * GetWindow(void) { return m_CurrentWindow; }  // tolua_export
	const cWindow * GetWindow(void) const { return m_CurrentWindow; }

	// tolua_begin

	/** Opens the specified window; closes the current one first using CloseWindow() */
	void OpenWindow(cWindow & a_Window);

	/** Closes the current window, resets current window to m_InventoryWindow. A plugin may refuse the closing if a_CanRefuse is true */
	void CloseWindow(bool a_CanRefuse = true);

	/** Closes the current window if it matches the specified ID, resets current window to m_InventoryWindow */
	void CloseWindowIfID(char a_WindowID, bool a_CanRefuse = true);

	cClientHandle * GetClientHandle(void) const { return m_ClientHandle.get(); }

	// tolua_end

	/** Get a copy of the PRNG for enchanting related generation, don't use this for other purposes.
	The PRNG's state is initialised with an internal seed, such that until PermuteEnchantmentSeed is called, this function returns the same PRNG. */
	MTRand GetEnchantmentRandomProvider();

	/** Permute the seed for enchanting related PRNGs, don't use this for other purposes. */
	void PermuteEnchantmentSeed();

	// tolua_begin

	void SendMessage              (const AString & a_Message);
	void SendMessageInfo          (const AString & a_Message);
	void SendMessageFailure       (const AString & a_Message);
	void SendMessageSuccess       (const AString & a_Message);
	void SendMessageWarning       (const AString & a_Message);
	void SendMessageFatal         (const AString & a_Message);
	void SendMessagePrivateMsg    (const AString & a_Message, const AString & a_Sender);
	void SendMessage              (const cCompositeChat & a_Message);
	void SendMessageRaw           (const AString & a_MessageRaw, eChatType a_Type = eChatType::ctChatBox);
	void SendSystemMessage        (const AString & a_Message);
	void SendAboveActionBarMessage(const AString & a_Message);
	void SendSystemMessage        (const cCompositeChat & a_Message);
	void SendAboveActionBarMessage(const cCompositeChat & a_Message);

	const AString & GetName(void) const;

	// tolua_end

	bool HasPermission(const AString & a_Permission);  // tolua_export

	/** Returns true iff a_Permission matches the a_Template.
	A match is defined by either being exactly the same, or each sub-item matches until there's a wildcard in a_Template.
	Ie. {"a", "b", "c"} matches {"a", "b", "*"} but doesn't match {"a", "b"} */
	static bool PermissionMatches(const AStringVector & a_Permission, const AStringVector & a_Template);  // Exported in ManualBindings with AString params

	/** Returns all the permissions that the player has assigned to them. */
	const AStringVector & GetPermissions(void) const { return m_Permissions; }  // Exported in ManualBindings.cpp

	/** Returns all the restrictions that the player has assigned to them. */
	const AStringVector & GetRestrictions(void) const { return m_Restrictions; }  // Exported in ManualBindings.cpp

	// tolua_begin

	/** Returns the full color code to use for this player, based on their rank.
	The returned value either is empty, or includes the cChatColor::Delimiter. */
	AString GetColor(void) const;

	/** Returns the player name prefix, may contain @ format directives */
	AString GetPrefix(void) const;

	/** Returns the player name suffix, may contain @ format directives */
	AString GetSuffix(void) const;

	/** Returns the name that is used in the playerlist. */
	AString GetPlayerListName(void) const;

	/** tosses the item in the selected hotbar slot */
	void TossEquippedItem(char a_Amount = 1);

	/** Removes one item from the the current equipped item stack, and attempts to add the specified item stack
	back to the same slot. If it is not possible to place the item in the same slot, tries to place the specified
	item elsewhere in the inventory. If this is not possible, then any remaining items are tossed. If the currently
	equipped slot is empty, its contents are simply set to the given Item.
	*/
	void ReplaceOneEquippedItemTossRest(const cItem &);

	/** tosses the item held in hand (when in UI windows) */
	void TossHeldItem(char a_Amount = 1);

	/** tosses a pickup newly created from a_Item */
	void TossPickup(const cItem & a_Item);

	/** Heals the player by the specified amount of HPs (positive only); sends health update */
	virtual void Heal(int a_Health) override;

	int    GetFoodLevel                 (void) const { return m_FoodLevel; }
	double GetFoodSaturationLevel       (void) const { return m_FoodSaturationLevel; }
	int    GetFoodTickTimer             (void) const { return m_FoodTickTimer; }
	double GetFoodExhaustionLevel       (void) const { return m_FoodExhaustionLevel; }

	/** Returns true if the player is satiated, i. e. their foodlevel is at the max and they cannot eat anymore */
	bool IsSatiated(void) const { return (m_FoodLevel >= MAX_FOOD_LEVEL); }

	void SetFoodLevel                 (int a_FoodLevel);
	void SetFoodSaturationLevel       (double a_FoodSaturationLevel);
	void SetFoodTickTimer             (int a_FoodTickTimer);
	void SetFoodExhaustionLevel       (double a_FoodExhaustionLevel);

	/** Adds to FoodLevel and FoodSaturationLevel, returns true if any food has been consumed, false if player "full" */
	bool Feed(int a_Food, double a_Saturation);

	/** Adds the specified exhaustion to m_FoodExhaustion. Expects only positive values. */
	void AddFoodExhaustion(double a_Exhaustion);

	/** Returns true if the player is currently in the process of eating the currently equipped item */
	bool IsEating(void) const { return m_EatingFinishTick >= 0_tick; }

	/** Returns true if the player is currently flying */
	bool IsFlying(void) const { return m_IsFlying; }

	/** Returns true if a player is sleeping in a bed. */
	bool IsInBed(void) const;

	/** Returns true if the player has thrown out a floater */
	bool IsFishing(void) const { return m_IsFishing; }

	void SetIsFishing(bool a_IsFishing, UInt32 a_FloaterID = cEntity::INVALID_ID) { m_IsFishing = a_IsFishing; m_FloaterID = a_FloaterID; }

	UInt32 GetFloaterID(void) const { return m_FloaterID; }

	// tolua_end

	/** Returns true if a player is standing normally, that is, in a neutral pose. */
	bool IsStanding() const;

	/** Tosses a list of items. */
	void TossItems(const cItems & a_Items);

	/** Sets a player's in-bed state.
	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_IsInBed);

	/** Starts eating the currently equipped item. Resets the eating timer and sends the proper animation packet */
	void StartEating(void);

	/** Finishes eating the currently equipped item. Consumes the item, updates health and broadcasts the packets */
	void FinishEating(void);

	/** Aborts the current eating operation */
	void AbortEating(void);

	virtual void KilledBy(TakeDamageInfo & a_TDI) override;

	virtual void Killed(cEntity * a_Victim) override;

	void Respawn(void);  // tolua_export

	void SetVisible( bool a_bVisible);  // tolua_export

	/** Saves all player data, such as inventory, to JSON. */
	void SaveToDisk(void);

	/** Loads the player data from the disk file.
	Sets m_World to the world where the player will spawn, based on the stored world name or the default world by calling LoadFromFile(). */
	void LoadFromDisk();

	/** Loads the player data from the specified file.
	Sets m_World to the world where the player will spawn, based on the stored world name or the default world.
	Returns true on success, false if the player wasn't found, and excepts with base std::runtime_error if the data couldn't be read or parsed. */
	bool LoadFromFile(const AString & a_FileName);

	const AString & GetLoadedWorldName() const { return m_CurrentWorldName; }

	/** Opens the inventory of any tame horse the player is riding.
	If the player is not riding a horse or if the horse is untamed, does nothing. */
	void OpenHorseInventory();

	/** Damage the player's equipped item by a_Damage, possibly less if the
	equipped item is enchanted. */
	void UseEquippedItem(short a_Damage = 1);

	/** Damage the player's equipped item by the amount of damage such an item
	is damaged by when used for a_Action */
	void UseEquippedItem(cItemHandler::eDurabilityLostAction a_Action);

	/** Damage the item in a_SlotNumber by a_Damage, possibly less if the
	equipped item is enchanted. */
	void UseItem(int a_SlotNumber, short a_Damage = 1);

	/** In UI windows, get the item that the player is dragging */
	cItem & GetDraggingItem(void) {return m_DraggingItem; }  // tolua_export

	/** In UI windows, set the item that the player is dragging */
	void SetDraggingItem(const cItem & a_Item);  // tolua_export

	// In UI windows, when inventory-painting:
	/** Clears the list of slots that are being inventory-painted. To be used by cWindow only */
	void ClearInventoryPaintSlots(void);

	/** Adds a slot to the list for inventory painting. To be used by cWindow only */
	void AddInventoryPaintSlot(int a_SlotNum);

	/** Returns the list of slots currently stored for inventory painting. To be used by cWindow only */
	const cSlotNums & GetInventoryPaintSlots(void) const;

	// tolua_begin

	/** Returns the current relative maximum speed (takes current sprinting / flying state into account) */
	double GetMaxSpeed(void) const;

	/** Gets the normal relative maximum speed */
	double GetNormalMaxSpeed(void) const { return m_NormalMaxSpeed; }

	/** Gets the sprinting relative maximum speed */
	double GetSprintingMaxSpeed(void) const { return m_SprintingMaxSpeed; }

	/** Gets the flying relative maximum speed */
	double GetFlyingMaxSpeed(void) const { return m_FlyingMaxSpeed; }

	/** Sets the normal relative maximum speed. Sends the update to player, if needed. */
	void SetNormalMaxSpeed(double a_Speed);

	/** Sets the sprinting relative maximum speed. Sends the update to player, if needed. */
	void SetSprintingMaxSpeed(double a_Speed);

	/** Sets the flying relative maximum speed. Sends the update to player, if needed. */
	void SetFlyingMaxSpeed(double a_Speed);

	/** Starts or stops crouching, if our current body stance permits, broadcasting the state change. */
	void SetCrouch(bool a_ShouldCrouch);

	/** Starts or stops elytra flight, if our current body stance permits, broadcasting the state change. */
	void SetElytraFlight(bool a_ShouldElytraFly);

	/** Starts or stops flying, broadcasting the state change. */
	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. */
	void SetCanFly(bool a_CanFly);

	/** Returns true if the player has a custom name. */
	bool HasCustomName(void) const { return !m_CustomName.empty(); }

	/** Returns the custom name of this player. If the player hasn't a custom name, it will return an empty string. */
	const AString & GetCustomName(void) const { return m_CustomName; }

	/** Sets the custom name of this player. If you want to disable the custom name, simply set an empty string.
	The custom name will be used in the tab-list, in the player nametag and in the tab-completion. */
	void SetCustomName(const AString & a_CustomName);

	/** Gets the last position that the player slept in
	This is initialised to the world spawn point if the player has not slept in a bed as of yet
	*/
	Vector3i GetLastBedPos(void) const { return m_LastBedPos; }

	/** Sets the player's bed (home / respawn) position to the specified position.
	Sets the respawn world to the player's world. */
	void SetBedPos(const Vector3i & a_Pos);

	/** Sets the player's bed (home / respawn) position and respawn world to the specified parameters. */
	void SetBedPos(const Vector3i & a_Pos, cWorld * a_World);

	// tolua_end

	// TODO lua export GetBedPos and GetBedWorld
	cWorld * GetBedWorld();

	/** Update movement-related statistics. */
	void UpdateMovementStats(const Vector3d & a_DeltaPos, bool a_PreviousIsOnGround);

	/** Whether placing the given blocks would intersect any entitiy */
	bool DoesPlacingBlocksIntersectEntity(const sSetBlockVector & a_Blocks);

	/** Returns the UUID that has been read from the client, or nil if not available. */
	const cUUID & GetUUID(void) const;  // Exported in ManualBindings.cpp

	// tolua_begin

	/** Returns wheter the player can fly or not. */
	virtual bool CanFly(void) const { return m_IsFlightCapable; }

	/** (Re)loads the rank and permissions from the cRankManager.
	Loads the m_Rank, m_Permissions, m_MsgPrefix, m_MsgSuffix and m_MsgNameColorCode members. */
	void LoadRank(void);

	/** Calls the block-placement hook and places the block in the world, unless refused by the hook.
	If the hook prevents the placement, sends the current block at the specified coords back to the client.
	Assumes that the block is in a currently loaded chunk.
	Returns true if the block is successfully placed. */
	bool PlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta);

	/** Sends the block in the specified range around the specified coord to the client
	as a block change packet.
	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.
	First the "placing" hooks for all the blocks are called, then the blocks are placed, and finally
	the "placed" hooks are called.
	If the any of the "placing" hooks aborts, none of the blocks are placed and the function returns false.
	Returns true if all the blocks are placed.
	Assumes that all the blocks are in currently loaded chunks. */
	bool PlaceBlocks(const sSetBlockVector & a_Blocks);

	/** Notify nearby wolves that the player or one of the player's wolves took damage or did damage to an entity
	@param a_Opponent the opponent we're fighting.
	@param a_IsPlayerInvolved Should be true if the player took or did damage, and false if one of the player's wolves took or did damage.
	*/
	void NotifyNearbyWolves(cPawn * a_Opponent, bool a_IsPlayerInvolved);

	/** Returns the progress mined per tick for the block a_Block as a fraction
	(1 would be completely mined)
	Depends on hardness values so check those are correct.
	Source: https://minecraft.gamepedia.com/Breaking#Calculation */
	float GetMiningProgressPerTick(BLOCKTYPE a_Block);

	/** Given tool, enchantments, status effects, and world position
	returns whether a_Block would be instantly mined.
	Depends on hardness values so check those are correct.
	Source: https://minecraft.gamepedia.com/Breaking#Instant_breaking */
	bool CanInstantlyMine(BLOCKTYPE a_Block);

	/** Adds an Item to the list of known items.
	If the item is already known, does nothing. */
	void AddKnownItem(const cItem & a_Item);

	// cEntity overrides:
	virtual void AttachTo(cEntity * a_AttachTo) override;
	virtual void Detach(void) override;
	virtual void Detach(bool a_IsTeleporting);
	virtual cItem GetEquippedWeapon(void) const override { return m_Inventory.GetEquippedItem(); }
	virtual cItem GetEquippedHelmet(void) const override { return m_Inventory.GetEquippedHelmet(); }
	virtual cItem GetEquippedChestplate(void) const override { return m_Inventory.GetEquippedChestplate(); }
	virtual cItem GetEquippedLeggings(void) const override { return m_Inventory.GetEquippedLeggings(); }
	virtual cItem GetEquippedBoots(void) const override { return m_Inventory.GetEquippedBoots(); }
	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:

	/** Xp Level stuff */
	enum
	{
		XP_TO_LEVEL15 = 255,
		XP_PER_LEVEL_TO15 = 17,
		XP_TO_LEVEL30 = 825
	} ;

	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. */
	AString m_Rank;

	/** All the permissions that this player has, based on their rank. */
	AStringVector m_Permissions;

	/** All the restrictions that this player has, based on their rank. */
	AStringVector m_Restrictions;

	/** All the permissions that this player has, based on their rank, split into individual dot-delimited parts.
	This is used mainly by the HasPermission() function to optimize the lookup. */
	AStringVectorVector m_SplitPermissions;

	/** All the restrictions that this player has, based on their rank, split into individual dot-delimited parts.
	This is used mainly by the HasPermission() function to optimize the lookup. */
	AStringVectorVector m_SplitRestrictions;


	// Message visuals:
	AString m_MsgPrefix, m_MsgSuffix;
	AString m_MsgNameColorCode;

	// Food-related variables:
	/** Represents the food bar, one point equals half a "drumstick" */
	int m_FoodLevel;

	/** "Overcharge" for the m_FoodLevel; is depleted before m_FoodLevel */
	double m_FoodSaturationLevel;

	/** Count-up to the healing or damaging action, based on m_FoodLevel */
	int m_FoodTickTimer;

	/** A "buffer" which adds up hunger before it is substracted from m_FoodSaturationLevel or m_FoodLevel. Each action adds a little */
	double m_FoodExhaustionLevel;

	/** Stores the player's inventory, consisting of crafting grid, hotbar, and main slots */
	cInventory m_Inventory;

	/** An item grid that stores the player specific enderchest contents */
	cItemGrid m_EnderChestContents;

	cWindow * m_CurrentWindow;
	cWindow * m_InventoryWindow;

	/** The player's last saved bed position */
	Vector3i m_LastBedPos;

	/** The name of the world which the player respawns in upon death.
	This is stored as a string to enable SaveToDisk to not touch cRoot, and thus can be safely called in the player's destructor. */
	std::string m_SpawnWorldName;

	/** The name of the world which the player currently resides in.
	Stored in addition to m_World to allow SaveToDisk to be safely called in the player's destructor. */
	std::string m_CurrentWorldName;

	/** The save path of the default world. */
	std::string m_DefaultWorldPath;

	eGameMode m_GameMode;

	/** The item being dragged by the cursor while in a UI window */
	cItem m_DraggingItem;

	std::shared_ptr<cClientHandle> m_ClientHandle;

	cSlotNums m_InventoryPaintSlots;

	/** Max speed, relative to the game default.
	1 means regular speed, 2 means twice as fast, 0.5 means half-speed.
	Default value is 1. */
	double m_NormalMaxSpeed;

	/** Max speed, relative to the game default max speed, when sprinting.
	1 means regular speed, 2 means twice as fast, 0.5 means half-speed.
	Default value is 1.3. */
	double m_SprintingMaxSpeed;

	/** Max speed, relative to the game default flying max speed, when flying.
	1 means regular speed, 2 means twice as fast, 0.5 means half-speed.
	Default value is 1. */
	double m_FlyingMaxSpeed;

	bool m_IsChargingBow;
	bool m_IsFishing;

	/** 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 */
	cTickTimeLong m_EatingFinishTick;

	/** Player Xp level */
	int m_LifetimeTotalXp;
	int m_CurrentXp;
	unsigned int m_EnchantmentSeed;

	int m_BowCharge;

	UInt32 m_FloaterID;

	cTeam * m_Team;

	cStatManager m_Stats;

	/** How long till the player's inventory will be saved
	Default save interval is #defined in PLAYER_INVENTORY_SAVE_INTERVAL */
	unsigned int m_TicksUntilNextSave;

	AString m_CustomName;

	/** Displayed skin part bit mask */
	int m_SkinParts;

	/** The main hand of the player */
	eMainHand m_MainHand;

	/** List on known recipes as Ids */
	std::set<UInt32> m_KnownRecipes;

	/** List of known items as Ids */
	std::set<cItem, cItem::sItemCompare> m_KnownItems;

	/** Called in each tick to handle food-related processing */
	void HandleFood(void);

	/** Called in each tick if the player is fishing to make sure the floater dissapears when the player doesn't have a fishing rod as equipped item. */
	void HandleFloater(void);

	/** Returns the filename for the player data based on the UUID given.
	This can be used both for online and offline UUIDs. */
	AString GetUUIDFileName(const cUUID & a_UUID);

	/** Pins the player to a_Location until Unfreeze() is called.
	If ManuallyFrozen is false, the player will unfreeze when the chunk is loaded. */
	void FreezeInternal(const Vector3d & a_Location, bool a_ManuallyFrozen);

	/** Returns how high the liquid is in percent. Used by IsInsideWater */
	float GetLiquidHeightPercent(NIBBLETYPE a_Meta);

	/** Checks if the player is inside of water */
	bool IsInsideWater();

	/** Returns the dig speed using the current tool on the block a_Block.
	Returns one if using hand.
	If the player is using a tool that is good to break the block the value is higher.
	If he has an enchanted tool with efficiency or he has a haste or mining fatique effect it gets multiplied by a specific factor depending on the strength of the effect or enchantment.
	In he is in water it gets divided by 5 except if his tool is enchanted with aqua affinity.
	If he is not on ground it also gets divided by 5.
	Source: https://minecraft.gamepedia.com/Breaking#Calculation */
	float GetDigSpeed(BLOCKTYPE a_Block);

	/** Add the recipe Id to the known recipes.
	If the recipe is already known, does nothing. */
	void AddKnownRecipe(UInt32 RecipeId);

	void TickFreezeCode();

	// cEntity overrides:
	virtual void ApplyArmorDamage(int DamageBlocked) override;
	virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = nullptr) override;
	virtual bool DoTakeDamage(TakeDamageInfo & TDI) override;
	virtual float GetEnchantmentBlastKnockbackReduction() override;
	virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk &) override { UNUSED(a_Dt); }
	virtual bool IsInvisible() const override;
	virtual bool IsRclking(void) const override { return IsEating() || IsChargingBow(); }
	virtual void OnAddToWorld(cWorld & a_World) override;
	virtual void OnRemoveFromWorld(cWorld & a_World) override;
	virtual void SpawnOn(cClientHandle & a_Client) override;
	virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;

} ;  // tolua_export