1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #ifndef CL_USER_ENTITY_H
24 #define CL_USER_ENTITY_H
31 #include "nel/misc/types_nl.h"
32 #include "nel/misc/vector.h"
34 #include "nel/3d/u_visual_collision_entity.h"
36 #include "nel/misc/cdb.h"
38 #include "player_cl.h"
39 #include "client_cfg.h"
43 #include "game_share/sp_type.h"
45 #include "game_share/r2_types.h"
51 using NLMISC::CVector
;
52 using NL3D::UVisualCollisionEntity
;
62 * Class to manage an user entity.
63 * \author Guillaume PUZIN
64 * \author Nevrax France
67 class CUserEntity
: public CPlayerCL
72 FirstPV
= 0, // First Person View
73 ThirdPV
// Third Person View
105 NLMISC_DECLARE_CLASS(CUserEntity
);
110 virtual ~CUserEntity();
112 /// Build the entity from a sheet.
113 virtual bool build(const CEntitySheet
*sheet
);
116 * Apply the motion to the entity.
118 void applyMotion(CEntityCL
*target
);
121 * Apply ForceLook (computed at prec applyMotion).
123 void applyForceLook();
126 * Update precollision
128 virtual void updatePreCollision(const NLMISC::TTime
&time
, CEntityCL
*target
);
131 * Update the position of the entity after the motion.
132 * \param target : pointer on the current target.
134 virtual void updatePosCombatFloatChanged(CEntityCL
*target
);
136 * Update the position of the entity after the motion.
137 * \param time : Time for the position of the entity after the motion.
138 * \param target : pointer on the current target.
140 virtual void updatePos(const NLMISC::TTime
&time
, CEntityCL
*target
);
142 /** Update the PACS position after the evalCollision. The entity position is set too. This is fast.
143 * If the entity position is too far from its PACS position, setGlobalPosition is called.
144 * After this call, the position.z is valid.
146 virtual void pacsFinalizeMove();
149 * Update the sound management to play user steps
151 void updateSound(const NLMISC::TTime
&time
);
153 virtual void snapToGround();
156 * 'true' if the user is dead too much and have to be disconnected.
158 bool permanentDeath() const {return _PermanentDeath
;}
161 /// Method called to change the mode (Combat/Mount/etc.).
162 virtual bool mode(MBEHAV::EMode m
);
163 /// Set the mode for the entity
164 virtual MBEHAV::EMode
mode() const {return _Mode
;}
166 /// Return the mount entity if the user is riding, otherwise NULL
167 CEntityCL
* getMountEntity();
169 /// Return the DB entry for the specified user's animal (NULL if not found)
170 NLMISC::CCDBNodeBranch
*getBeastDBEntry( CLFECOMMON::TClientDataSetIndex uid
);
172 /** To Inform about an entity removed (to remove from selection for example).
173 * This will remove the entity from the target.
174 * \param slot : Slot of the entity that will be removed.
176 virtual void slotRemoved(const CLFECOMMON::TCLEntityId
&slot
);
178 /** Change the entity selected.
179 * \param slot : slot now selected (CLFECOMMON::INVALID_SLOT for an empty selection).
180 * \warning Can be different from the entity targeted (in combat mode for example).
182 virtual void selection(const CLFECOMMON::TCLEntityId
&slot
);
183 /** Return the entity selected.
184 * \return CLFECOMMON::TCLEntityId : slot currently selected (CLFECOMMON::INVALID_SLOT for an empty selection).
185 * \warning Can be different from the entity targeted (in combat mode for example).
187 virtual const CLFECOMMON::TCLEntityId
&selection() const {return _Selection
;}
189 /** Set the trader (see also trader() and interlocutor())
190 * \param slot : trader slot (CLFECOMMON::INVALID_SLOT if no trader).
192 virtual void trader(const CLFECOMMON::TCLEntityId
&slot
);
193 /** Return the trader entity that will be turned towards the user entity (client-side)
194 * and other stuff such as distance checking (see also interlocutor())
195 * \return CLFECOMMON::TCLEntityId : slot of the trader (CLFECOMMON::INVALID_SLOT if no trader).
197 virtual const CLFECOMMON::TCLEntityId
&trader() const {return _Trader
;}
199 /** Set the current interlocutor entity that will be turned towards the user entity (client-side).
200 * This one is for dyn-chat, while trader() is for bot-chat.
201 * \param slot : interlocutor slot (CLFECOMMON::INVALID_SLOT if no interlocutor).
203 void interlocutor( const CLFECOMMON::TCLEntityId
&slot
);
204 /** Return the current interlocutor entity that will be turned towards the user entity (client-side).
205 * This one is for dyn-chat, while trader() is for bot-chat.
206 * \return CLFECOMMON::TCLEntityId : slot of the interlocutor (CLFECOMMON::INVALID_SLOT if no interlocutor).
208 const CLFECOMMON::TCLEntityId
&interlocutor() const {return _Interlocutor
;}
210 /// Method to place the user to attack the target and attack.
212 /// Method to attack the target.
214 /// Method to disengage the target.
216 /// Method to attack the target, with a special phrase
217 void attackWithPhrase();
218 /// your current target become the target of your current one.
220 /// the entity target in the slot become the target of your current one.
221 void assist(uint slot
);
223 /// Ask fot the client to sit/stand ('true' to sit).
225 /// Return true if the user can sit.
228 /// Set the user away from keyboard (or not), txt can be customized
229 void setAFK(bool b
, std::string afkTxt
="");
231 /// Roll a dice and tell the result around
232 void rollDice(sint16 min
, sint16 max
, bool local
);
234 /// return true if user can engage melee combat, else return false and display system msg
235 bool canEngageCombat();
239 * Method to manage the user velocity.
243 * Set the velocity when the user walks.
244 * \param velocity : new velocity for the user when he walks.
246 inline void walkVelocity(float velocity
)
248 _WalkVelocity
= velocity
;
250 _CurrentVelocity
= _WalkVelocity
;
253 * Get the velocity when the user walks.
254 * \return float : User velocity when he walks.
256 inline float walkVelocity() const {return _WalkVelocity
;}
258 * Set the velocity when the user runs.
259 * \param velocity : new velocity for the user when he runs.
261 inline void runVelocity(float velocity
)
263 _RunVelocity
= velocity
;
265 _CurrentVelocity
= _RunVelocity
;
268 * Get the velocity when the user runs.
269 * \return float : User velocity when he runs.
271 inline float runVelocity() const {return _RunVelocity
;}
274 * Get the current velocity of the user.
275 * \return float : Current User velocity.
277 inline float currentVelocity() const {return _CurrentVelocity
;}
280 * Switch velocity between Run and Walk.
281 * \param userRequest : true if user asked it
283 void switchVelocity(bool userRequest
= true);
286 * Test if user is running
288 bool running() const { return _Run
; }
291 /// Get the front velocity.
292 inline float frontVelocity() const {return _FrontVelocity
;}
293 /// Set the front velocity.
294 inline void frontVelocity(float velocity
) {_FrontVelocity
= velocity
;}
296 /// Get the lateral velocity.
297 inline float lateralVelocity() const {return _LateralVelocity
;}
298 /// Set the lateral velocity.
299 inline void lateralVelocity(float velocity
) {_LateralVelocity
= velocity
;}
301 // get the velocity vector of the entity
302 NLMISC::CVector
getVelocity() const;
304 inline void setSpeedServerAdjust(float speed
) {_SpeedFactor
.addFactorValue(speed
);}
306 /// Check if the mount is able to run, and force walking mode if not
307 void checkMountAbleToRun();
312 inline void eyesHeight(float h
) {_EyesHeight
= h
;}
314 /// Head Pitch methods
315 void setHeadPitch(double hp
);
316 double getHeadPitch() const {return _HeadPitch
;}
317 void rotHeadVertically(float ang
);
319 /// Get the playersheet
320 inline const CPlayerSheet
*sheet() const {return _Sheet
;}
323 /// rotate the body on the left or right (front changes).
324 void rotate(float ang
);
327 /// TODO: Ben tests for landscape pacs bug
328 const NLPACS::UMovePrimitive
*getMovePrimitive() const { return _Primitive
; }
330 /// Remove the primitive
331 virtual void removePrimitive();
332 /// Create a primitive for the entity.
333 virtual void computePrimitive();
335 /// Remove the check primitive
336 void removeCheckPrimitive();
338 /// Is the user selectable (first or third person view for example).
339 bool selectable() const {return _Selectable
;}
340 /// Set is the user is selectable or not.
341 void selectable(bool s
) {_Selectable
= s
;}
343 /// Return if the user is already busy (combat/bo chat/loot/ etc.).
346 /// Return 'true' if the user is on a mount.
347 bool isOnMount() const {return _OnMount
;}
350 * Methods only here for the debug.
353 /// Display Debug Information.
354 virtual void displayDebug(float x
, float &y
, float lineStep
);
357 void updateVisualDisplay();
359 /// Return 'true' is an attack animation is currently playing.
360 bool isAttacking() const {return _AnimAttackOn
;}
362 /// Show/Hide the user light.
365 /// Display dmg/heal numbers above the head.
366 virtual void displayModifiers();
369 * Methods about the view (First/Third Person View).
372 /// Change the View (First/Third Person View).
373 void viewMode(TView viewMode
, bool changeView
=true);
374 /// Return the current View Mode.
375 TView
viewMode() const {return _ViewMode
;}
376 /// Toggle Camera (First/Third Person)
378 /// Force Camera First Person View
379 void forceCameraFirstPerson();
382 /// Return the entity scale. (return 1.0 if there is any problem).
383 virtual float getScale() const;
384 /// Return 'true' is the entity is displayed.
385 virtual bool isVisible() const;
387 /// Return true if the user is indoor and the CFG want to force the FPV Indoor.
388 bool forceIndoorFPV();
389 bool moveTo() const {return (_MoveToSlot
!= CLFECOMMON::INVALID_SLOT
);}
390 /// Return true if the User is following an entity.
391 bool follow() const {return _FollowMode
;}
392 /// set true to resetCameraRot if you want that camera rotation follow
393 void enableFollow(bool resetCameraRot
);
394 void disableFollow();
395 // when the user request to move the head pitch, stop the "follow mode" to force it
396 void stopForceHeadPitchInFollow();
397 /// Method to move to someone else. NB: resetAnyMoveTo() is called first
398 void moveTo(CLFECOMMON::TCLEntityId slot
, double dist
, TMoveToAction action
);
399 /// Method to move to someone else for a mission. NB: resetAnyMoveTo() is called first
400 void moveToMission(CLFECOMMON::TCLEntityId slot
, double dist
, uint32 id
);
401 /// Method to move to someone else for a ring mission. NB: resetAnyMoveTo() is called first
402 void moveToMissionRing(CLFECOMMON::TCLEntityId slot
, double dist
, uint32 id
);
403 /** Method to move to someone else, for foraging extraction
404 * The caller MUST call after CSPhraseManager::clientExecute(), to increment action counter
405 * NB: resetAnyMoveTo() is called first
407 void moveToExtractionPhrase(CLFECOMMON::TCLEntityId slot
, double dist
, uint phraseMemoryLine
, uint phraseMemorySlot
, bool cyclic
);
408 /** Method to begin a spire construction
409 * The caller MUST call after CSPhraseManager::clientExecute(), to increment action counter
410 * NB: resetAnyMoveTo() is called first
412 void moveToTotemBuildingPhrase(CLFECOMMON::TCLEntityId slot
, double dist
, uint phraseMemoryLine
, uint phraseMemorySlot
, bool cyclic
);
413 /// Reset any MoveTo. NB: if the current moveTo is a moveToCombatPhrase() or a moveToExtractionPhrase(), decrement action counter
414 void resetAnyMoveTo();
415 /** Launch the Action Once the Move is done.
416 * \param CEntityCL * : pointer on the destination entity.
417 * \warning entity pointer must be valid(allocated).
419 void moveToAction(CEntityCL
*ent
);
420 /// Send the position and orientation to the server.
421 bool sendToServer(NLMISC::CBitMemStream
&out
);
422 /// Fill the msg to know if the user is well placed to fight.
423 bool msgForCombatPos(NLMISC::CBitMemStream
&out
);
424 /// Check the User Position according to the server code.
426 /// Check a position according to the server code.
427 bool testPacsPos(NLMISC::CVectorD
& pos
);
428 /// Teleport the player (remove selection, re-init checkPos, etc.).
429 void tp(const NLMISC::CVectorD
&dest
);
430 /// Teleport the player to correct his position.
431 void correctPos(const NLMISC::CVectorD
&dest
);
435 /// get the level of the player (max of all skills)
436 sint
getLevel() const;
438 /// After a few time, if the user is still in collision with someone else, remove collisions with other entitites.
439 void startColTimer();
440 /// Called when the user is no more in collision with another entity.
443 /// Make the character transparent if the mouse is under it (params is if we must make it transparent or opaque)
444 virtual void makeTransparent(bool t
);
445 virtual void setDiffuse(bool onOff
, NLMISC::CRGBA diffuse
);
447 /// false if in first person mode
448 virtual bool canCastShadowMap() const;
450 /// Return the Entity Current Speed.
451 virtual double speed() const;
453 /// assert(target). NB: this engage (moveToCombatPhrase) if in melee and to far, or directly launch the action
454 void executeCombatWithPhrase(CEntityCL
*target
, uint32 memoryLine
, uint32 memoryIndex
, bool cyclic
);
456 /// equip with the last weapon used of with the best weapon that can be found in inventory
457 void autoEquipWithLastUsedWeapons();
459 /// save the last weapon(s) used in fight or weapons in hand before tool auto-equip
460 void rememberWeaponsInHand();
462 /// overriden beginCast method
463 virtual void beginCast(const MBEHAV::CBehaviour
&behaviour
);
465 /// Return the walk speed applicable when riding
466 float getMountWalkVelocity() const { return _MountSpeeds
.getWalkSpeed(); }
468 /// Return the run speed applicable when riding
469 float getMountRunVelocity() const { return _MountSpeeds
.getRunSpeed(); }
471 /// \name R2 specific
473 // R2 char mode (player, dm, anim, edit) NB: automatically affect the camera max distance and player run/walk speed
474 void setR2CharMode(R2::TCharMode mode
);
475 R2::TCharMode
getR2CharMode() const {return _R2CharMode
;}
476 // re-update view camera dist max, and walk/run speed according to current R2 char mode
477 void flushR2CharMode() {setR2CharMode(_R2CharMode
);}
479 // When a player control a npc (in a ring shard) then he must adapt his speed on the Npc speed.
480 void updateNpcContolSpeed();
481 bool isInNpcControl() const;
483 /// cancel current action
484 void cancelAllPhrases();
486 /// true if current behaviour allows to change front
487 bool canChangeFront();
489 string
getLoginName()
491 if (_LoginName
.empty())
492 _LoginName
= getDisplayName();
498 class CSpeedFactor
: public NLMISC::ICDBNode::IPropertyObserver
505 /// Return the speed factor.
506 float getValue() const { return _Value
* _ServerFactor
; }
507 void setFactorValue(float value
) {_ServerFactor
= value
;}
508 void addFactorValue(float value
) {
509 _ServerFactor
+= value
;
510 if (_ServerFactor
> 1.0)
512 if (_ServerFactor
< 0.1)
516 virtual void serial(NLMISC::IStream
&f
) {f
.serial(_Value
);}
518 /// Method called when the ping message is back.
519 virtual void update(NLMISC::ICDBNode
* leaf
);
532 /// Return true if the mount can run. Precondition: UserEntity->isRiding().
534 virtual void serial(NLMISC::IStream
&/* f */) {}
537 class CMountSpeeds
: public NLMISC::ICDBNode::IPropertyObserver
544 /// Return the walk speed when riding
545 float getWalkSpeed() const { return _WalkSpeed
; }
546 /// Return the run speed when riding
547 float getRunSpeed() const { return _RunSpeed
; }
549 /// Method called when the value is changed
550 virtual void update(NLMISC::ICDBNode
* leaf
);
556 /// Speed Factor to use for the user sent by the server to respect magical spells
557 CSpeedFactor _SpeedFactor
;
558 /// The current maximum speed of the mount (if any)
559 CMountHunger _MountHunger
;
560 /// An observer of the current mount speeds
561 CMountSpeeds _MountSpeeds
;
562 /// Velocity : Front and Lateral
563 float _FrontVelocity
;
564 float _LateralVelocity
;
565 /// Speed adjustement from gpms
566 float _SpeedServerAdjust
;
569 /// Height of the eyes (camera).
571 /// 'True' if the user is running else is walking.
573 /// 'True' if the user & mount should run but are walking because of the mount unability to run
575 /// Speed when the user walks.
577 /// Speed when the user runs.
579 /// Current User Velocity.
580 float _CurrentVelocity
;
581 /// Slot Currently Selected (can be different from _TargetSlot).
582 CLFECOMMON::TCLEntityId _Selection
;
583 /// Trader Slot (bot chat)
584 CLFECOMMON::TCLEntityId _Trader
;
585 /// Interlocutor Slot (dyn chat)
586 CLFECOMMON::TCLEntityId _Interlocutor
;
588 bool _PermanentDeath
;
590 /// Last position validated by the Check system
591 NLMISC::CVectorD _LastPositionValidated
;
592 /// Last Validated Global Position.
593 NLPACS::UGlobalPosition _LastGPosValidated
;
594 /// Last Global Position sent to the server (in fact it's a normal position sent).
595 NLPACS::UGlobalPosition _LastGPosSent
;
596 /// Primitive used to check if the server will accept the current move.
597 NLPACS::UMovePrimitive
*_CheckPrimitive
;
599 CLFECOMMON::TCLEntityId _MoveToSlot
;
601 TMoveToAction _MoveToAction
;
602 uint _MoveToPhraseMemoryLine
; // used for extraction as well
603 uint _MoveToPhraseMemorySlot
; // used for extraction phrase as well
604 bool _MoveToPhraseCyclic
;
605 uint32 _MoveToMissionId
; // Used for both mission option and mission ring
606 /// Time in MS when the User started beiing in collision with anything that avoid him to do an Action (and still is).
607 sint64 _MoveToColStartTime
;
610 /// CSkill points observer
611 class CSkillPointsObserver
: public NLMISC::ICDBNode::IPropertyObserver
616 /// From ICDBNode::IPropertyObserver
617 virtual void update(NLMISC::ICDBNode
* node
);
619 CSkillPointsObserver _SkillPointObs
[EGSPD::CSPType::EndSPType
];
621 class CInvisibleObserver
: public NLMISC::ICDBNode::IPropertyObserver
624 virtual void update(NLMISC::ICDBNode
* node
);
626 CInvisibleObserver _InvisibleObs
;
629 class CFameObserver
: public NLMISC::ICDBNode::IPropertyObserver
634 /// From ICDBNode::IPropertyObserver
635 virtual void update(NLMISC::ICDBNode
* node
);
637 std::vector
<CFameObserver
*> _FamesObs
;
640 /// Initialize properties of the entity (according to the class).
641 virtual void initProperties();
643 /// Update Entity Position.
644 virtual void updateVisualPropertyPos (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
, const NLMISC::TGameCycle
&pI
);
645 /// Update Entity Orientation.
646 virtual void updateVisualPropertyOrient (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
647 /// Update Entity Behaviour.
648 virtual void updateVisualPropertyBehaviour (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
649 /// Update Entity Name.
650 virtual void updateVisualPropertyName (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
651 /// Update Entity Target.
652 virtual void updateVisualPropertyTarget (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
653 /// Update Entity Mode.
654 virtual void updateVisualPropertyMode (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
655 /// Update Entity Visual Property A
656 virtual void updateVisualPropertyVpa (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
657 /// Update Entity Visual Property B
658 virtual void updateVisualPropertyVpb (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
659 /// Update Entity Visual Property C
660 virtual void updateVisualPropertyVpc (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
661 /// Update Entity Mount
662 virtual void updateVisualPropertyEntityMounted (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
663 /// Update Entity Rider
664 virtual void updateVisualPropertyRiderEntity (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
666 virtual void updateVisualPropertyTargetList (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
, uint listIndex
);
668 virtual void updateVisualPropertyVisualFX (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
670 virtual void updateVisualPropertyPvpMode (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
672 virtual void updateVisualPropertyOutpostInfos (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
674 virtual void updateVisualPropertyPvpClan (const NLMISC::TGameCycle
&gameCycle
, const sint64
&prop
);
677 /// Apply the behaviour for the user.
678 virtual void applyBehaviour(const CBehaviourContext
&behaviour
);
679 /// Method to Flag the character as dead and do everything needed.
680 virtual void setDead();
682 /// Mount the mount in _Mount
685 /** Return the current max speed for the entity in meter per sec
686 * The method return a max according to the speed factor (given by the server)
687 * It's also return a value according to the landscape (water)
688 * Also managed mounts
690 virtual double getMaxSpeed() const;
692 /// Read/Write Variables from/to the stream.
693 virtual void readWrite(NLMISC::IStream
&f
);
694 /// To call after a read from a stream to re-initialize the entity.
698 /// Extract RM from a select forage source
706 /// TO know if the user is on a mount at the moment.
708 /// Keep track of last hidden mount when switching to FPV mode
709 CLFECOMMON::TCLEntityId _HiddenMount
;
710 /// Is the attack animation is currently playing.
712 /// Current View Mode (First/Third Person View).
714 /// 'true' if the collisions between the user and other entities are removed.
716 /// 'true' if the User is in collision with someone else.
718 /// Time in MS when the User started beiing in collision with another entity (and still is).
719 sint64 _ColStartTime
;
721 /// Force Look also modify the head pitch in First person
722 bool _FollowForceHeadPitch
;
723 /// The Head Offset to follow is kept here.
724 float _FollowHeadOffset
;
726 /// Check if the user is not already well placed.
727 void moveToCheckStartDist(CLFECOMMON::TCLEntityId slot
, double dist
, TMoveToAction action
);
729 /// forceLook an entity (follow or moveTo)
730 CLFECOMMON::TCLEntityId _ForceLookSlot
;
731 void forceLookEntity(const NLMISC::CVectorD
&dir2targ
, bool updateHeadPitch
, bool start
= false);
732 void startForceLookEntity(CLFECOMMON::TCLEntityId slot
);
734 /** Method to move to someone else, for special melee combat
735 * The caller MUST call after CSPhraseManager::clientExecute(), to increment action counter
736 * NB: resetAnyMoveTo() is called first
738 void moveToCombatPhrase(CLFECOMMON::TCLEntityId slot
, double dist
, uint phraseMemoryLine
, uint phraseMemorySlot
, bool phraseCyclic
);
740 /// For executeCombatWithPhrase
741 CLFECOMMON::TCLEntityId _LastExecuteCombatSlot
;
743 /// R2: to know in which mode is the current entity (affect camera view and run speed)
744 R2::TCharMode _R2CharMode
;
746 /// snapshot of a CItemImage
770 CItemSnapshot( const CItemImage
& i
);
772 /// previous items in hand before they have been changed by an auto-equip due to an action (ex: forage)
773 CItemSnapshot _PreviousRightHandItem
;
774 CItemSnapshot _PreviousLeftHandItem
;
776 std::string _LoginName
;
779 /// Out game received position
780 extern NLMISC::CVectorD UserEntityInitPos
;
781 extern NLMISC::CVector UserEntityInitFront
;
782 extern CUserEntity
*UserEntity
;
784 /// char and account time properties
785 extern uint32 CharFirstConnectedTime
;
786 extern uint32 CharPlayedTime
;
788 /// Max distance between player and extracted forage source
789 extern const double MaxExtractionDistance
;
791 #endif // CL_USER_ENTITY_H
793 /* End of user_entity.h */