Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / gpm_service / world_entity.h
blobaad4c4f4888c6aa2b3bb958b0f9c4642ca4faf47
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef NL_WORLD_ENTITY_H
20 #define NL_WORLD_ENTITY_H
22 #include "nel/misc/types_nl.h"
23 #include "nel/misc/block_memory.h"
24 #include "nel/misc/debug.h"
25 #include "nel/misc/time_nl.h"
27 #include "nel/pacs/u_move_container.h"
28 #include "nel/pacs/u_move_primitive.h"
30 #include "gpm_utilities.h"
31 #include "gpm_defs.h"
33 #include "game_share/mirror_prop_value.h"
34 #include "game_share/ryzom_mirror_properties.h"
35 #include "server_share/msg_gpm_service.h"
37 #include <deque>
39 class CCell;
40 class CPlayerInfos;
41 class CWorldEntity;
43 typedef std::list<CWorldEntity*> TWorldEntityList;
45 struct CVisionEntry
48 CVisionEntry() { }
49 CVisionEntry(CWorldEntity* e, uint32 m, uint32 d) : Entity(e), Mask(m), Distance(d) { }
51 CWorldEntity* Entity;
52 uint32 Mask;
53 uint32 Distance;
56 /**
57 * World entity contained all properties positions in world for an entity
58 * \author Alain Saffray
59 * \author Nevrax France
60 * \date 2002
62 class CWorldEntity
64 friend class NLMISC::CBlockMemory<CWorldEntity>;
66 public:
67 typedef CSimpleSmartPointer<CWorldEntity> CWorldEntitySmartPointer;
69 enum TEntityType
71 Player = 0,
72 Object,
73 Trigger,
74 AI,
75 Unknown
79 enum TVisionState // Enum of vision state for this entity
81 Ready = 0, // ready to use
82 Checked, // in check
83 Seen, // entity is seen by another
87 public:
89 NLMISC::CEntityId Id; // Id of entity
90 TDataSetRow Index;
92 CMirrorPropValue1DS<TYPE_POSX> X; // Coordinate X in world in unit
93 CMirrorPropValue1DS<TYPE_POSY> Y; // Coordinate Y in world in unit
94 CMirrorPropValue1DS<TYPE_POSZ> Z; // Coordinate Z in world in unit
95 CMirrorPropValue1DS<TYPE_POSX> LocalX; // Local Coordinate X in world in unit
96 CMirrorPropValue1DS<TYPE_POSY> LocalY; // Local Coordinate X in world in unit
97 CMirrorPropValue1DS<TYPE_POSZ> LocalZ; // Local Coordinate X in world in unit
98 CMirrorPropValue1DS<TYPE_ORIENTATION> Theta; // Heading in world
99 CMirrorPropValue1DS<TYPE_SHEET> Sheet; // Id sheet of entity
100 CMirrorPropValue1DS<NLMISC::TGameCycle> Tick; // GameCycle of other properties
101 CMirrorPropValue1DS<TYPE_CELL> Cell; // Current XY Cell where entity is
102 CMirrorPropValue1DS<TYPE_VISION_COUNTER> VisionCounter; // Number of times this entity is seen by players
103 uint32 PlayersSeeingMe;
104 CWorldEntity* ClosestPlayer;
106 CMirrorPropValue1DS<TYPE_WHO_SEES_ME> WhoSeesMe;
108 bool Dead; // Are player dead or alive
110 uint32 PatatEntryIndex; // The patat entry for the _PatatSubscribeManager
112 CCell *CellPtr; // pointer on cell where entity is
114 TWorldEntityList::iterator ListIterator; // Iterator on entity in world entity list
115 TWorldEntityList::iterator PrimIterator; // Iterator on entity in prmitived entity list
117 uint8 Continent; // index on the continent on which the player is located
118 bool PosInitialised; // Pos was initialised by mirror
119 bool UsePrimitive; // entity uses a primitive normally
120 bool ForceUsePrimitive; // forces entity to use a primitive temporarily (mount, etc.)
121 NLPACS::UMovePrimitive *Primitive; // Primitive for collision systeme (PACS)
122 NLPACS::UMoveContainer *MoveContainer; // MoveContainer entity is in
123 uint32 TickLock;
125 CWorldEntitySmartPointer Previous;
126 CWorldEntitySmartPointer Next;
128 CPlayerInfos *PlayerInfos; // The player infos associated to this entity (if there is some)
130 CWorldEntitySmartPointer Parent; // Which is entity we are in/on (ex: mount, ferry)
131 std::vector<CWorldEntitySmartPointer> Children; // Which are the child we contain
132 CWorldEntitySmartPointer Control; // Which entity is controlling us (ex: rider, pilot...)
134 bool ForceDontUsePrimitive; // forces entity not to use a primitive temporarily (mount, etc.)
135 bool CheckMotion;
136 bool HasVision; // Entity has vision
138 std::vector<CEntitySheetId> Content;
140 bool TempVisionState; // temporary flag for vision delta, telling if the entity is now visible
141 bool TempControlInVision; // temporary flag for vision delta, telling if the controller entity (if any) is in vision
142 bool TempParentInVision; // temporary flag for vision delta, telling if the parent (controlled) entity (if any) is in vision
144 sint32 RefCounter; // Number of references on this entity -- used by smart pointer
146 public:
148 * destructor
150 ~CWorldEntity();
153 * Init
154 * \param id is entity's CEntityId
156 void init( const NLMISC::CEntityId& id, const TDataSetRow &index );
159 * Display debug
161 void display(NLMISC::CLog *log = NLMISC::InfoLog) const;
164 * create primitive for fiche type entity
165 * \param ficheId is sheet type Id of entity
166 * \param pMoveContainer adress of the move container
167 * \param worldImage numvber of the world image in which the primitive is to be inserted
168 * \return pointer on PACS primitve
170 void createPrimitive(NLPACS::UMoveContainer *pMoveContainer, uint8 worldImage);
173 * Removes primitive allocated previously
175 void removePrimitive();
179 * removes entity from the cell it is in
181 //void removeFromCellAsEntity();
184 * removes object from the cell it is in
186 //void removeFromCellAsObject();
189 /// Test if entity is linked in a cell
190 bool isLinked() const { return CellPtr != NULL; }
192 /// Get (const) CCell point in which entity is
193 const CCell* getCell() const { return CellPtr; }
196 /// Tests if entity uses a pacs primitive
197 bool hasPrimitive() const { return Primitive != NULL && !ForceDontUsePrimitive; }
199 /// local motion
200 bool localMotion() const { return Parent != NULL; }
202 /// has control ?
203 bool hasControl() const { return Parent != NULL && Parent->Control == this; }
205 /// is controlled ?
206 bool isControlled() const { return Control != NULL; }
208 /// has children
209 bool hasChildren() const { return !Children.empty(); }
211 /// remove from children
212 void removeFromChildren(CWorldEntity *entity)
214 std::vector<CWorldEntitySmartPointer>::iterator it;
215 for (it=Children.begin(); it!=Children.end(); ++it)
216 if ((CWorldEntity*)(*it) == entity)
217 it = Children.erase(it);
219 entity->Parent = NULL;
220 Control = NULL;
223 /// get controlled
224 CWorldEntity *getControlled()
226 if (!hasControl())
227 return NULL;
229 CWorldEntity *parent = Parent;
230 while (parent->hasControl())
231 parent = parent->Parent;
233 return parent;
236 /// update local or global position
237 void updatePosition(sint32 x, sint32 y, sint32 z, float theta, NLMISC::TGameCycle cycle, bool interior, bool water)
239 if (localMotion())
241 LocalX = x;
242 LocalY = y;
243 LocalZ = z;
245 setPosition(x + Parent->X(), y + Parent->Y(), z + Parent->Z(), true, interior, water);
247 else
249 setPosition(x, y, z, false, interior, water);
252 Tick = cycle;
253 Theta = theta;
255 // force position as valid
256 PosInitialised = true;
259 /// update global position for local motion
260 void updatePosition(bool interior, bool water)
262 if (localMotion())
264 setPosition(LocalX() + Parent->X(), LocalY() + Parent->Y(), LocalZ() + Parent->Z(), true, interior, water);
268 /// Set position
269 void setPosition(sint32 x, sint32 y, sint32 z, bool local, bool interior, bool water)
271 X = x;
272 Y = y;
273 Z = (z&(~7)) + (local ? 1 : 0) + (interior ? 2 : 0) + (water ? 4 : 0);
276 /// update position using move primitive
277 void updatePositionUsingMovePrimitive(uint wi);
281 /// get Type of the entity
282 TEntityType getType() const
284 return _Type;
288 private:
290 /// Is in interior
291 bool interior() const
293 return (Z()&2) != 0;
296 /// Type of the entity
297 TEntityType _Type;
299 public:
301 /// Creates a new entity (new equivalent). This must be initialised later using init();
302 static CWorldEntity* create();
304 /// Removes an entity (delete equivalent).
305 static void remove(CWorldEntity *entity);
307 protected:
309 * Default constructor, used because of CBlockMemory
311 CWorldEntity() {}
313 private:
315 /// Static cell allocator
316 static NLMISC::CBlockMemory<CWorldEntity> _EntityAllocator;
320 typedef CWorldEntity::CWorldEntitySmartPointer CWorldEntityPtr;
322 /// A list of CWorldEntity, referred by smart pointers. First template param is the pointed type, second param is the pointer storage type (here smart pointer)
323 typedef CObjectList<CWorldEntity, CWorldEntityPtr> TEntityList;
327 * Player Infos : contains all information specific to players (like vision and original front end)
328 * \author David Fleury
329 * \author Nevrax France
330 * \date 2002
332 class CPlayerInfos
334 friend class NLMISC::CBlockMemory<CPlayerInfos>;
336 public:
337 /// init
338 void init(const NLMISC::CEntityId &id, NLNET::TServiceId feId, CWorldEntity *entity)
340 WhoICanSee = 0xffffffff;
342 Next = NULL;
343 Previous = NULL;
344 ActivateSlot0 = false;
345 DesactivateSlot0 = false;
346 Slot0Active = false;
348 uint i;
349 for (i = MAX_SEEN_ENTITIES-1 ; i > 0; --i)
350 FreeSlots.push_back( i );
352 for (i = 0 ; i < MAX_SEEN_ENTITIES ; ++i)
353 Slots[i] = NULL;
355 LastVisionTick = 0;
357 _PlayerId = id;
358 FeId = feId;
359 Entity = entity;
361 CheckSpeed = true;
362 Indoor = false;
363 EnableVisionProcessing = true;
366 /// get playerId
367 inline const NLMISC::CEntityId &getPlayerId() const { return _PlayerId; }
370 * Display debug
372 void display(NLMISC::CLog *log = NLMISC::InfoLog) const;
374 private:
375 /// the player Id
376 NLMISC::CEntityId _PlayerId;
378 /// default constructor
379 CPlayerInfos() { }
381 public:
382 /// original front end Id
383 NLNET::TServiceId FeId;
385 /// front end datas
386 TMapFrontEndData::iterator ItFrontEnd;
388 /// iterator in the update player list
389 TPlayerList::iterator ItUpdatePlayer;
391 /// tick at last vision update
392 NLMISC::TGameCycle LastVisionTick;
394 /// Delay vision till cycle
395 NLMISC::TGameCycle DelayVision;
398 typedef CUnsafeConstantSizeStack<uint16, MAX_SEEN_ENTITIES+1> TSlotStack;
400 /// list of free slots for vision
401 TSlotStack FreeSlots;
403 /// The world entity for this player
404 CWorldEntityPtr Entity;
406 /// Previous player in list
407 CPlayerInfos* Previous;
408 /// Next player in list
409 CPlayerInfos* Next;
411 /// slots for this player
412 CWorldEntityPtr Slots[MAX_SEEN_ENTITIES];
414 bool ActivateSlot0;
415 bool DesactivateSlot0;
416 bool Slot0Active;
418 bool EnableVisionProcessing;
420 bool CheckSpeed;
421 bool Indoor;
423 /// Who I can see flag field
424 uint32 WhoICanSee;
426 #ifdef RECORD_LAST_PLAYER_POSITIONS
427 /// Distance history
428 std::deque< std::pair<NLMISC::CVectorD, uint> > DistanceHistory;
429 #endif
431 float meanSpeed() const
433 #ifdef RECORD_LAST_PLAYER_POSITIONS
434 float dist = 0.0f;
435 uint i;
436 for (i=0; i+1<DistanceHistory.size(); ++i)
438 double dx = DistanceHistory[i+1].first.x-DistanceHistory[i].first.x,
439 dy = DistanceHistory[i+1].first.y-DistanceHistory[i].first.y;
441 dist += (float)sqrt(dx*dx + dy*dy);
444 return DistanceHistory.size() > 1 ? (dist/(DistanceHistory.size()-1)) : 0.0f;
445 #else
446 return 0.0f;
447 #endif
451 struct CPlayerPos
453 NLMISC::TGameCycle AtTick;
454 NLPACS::UGlobalPosition GPos;
455 NLMISC::CVectorD Motion;
456 float Theta;
459 std::deque<CPlayerPos> PosHistory;
461 public:
462 /// Creates a new entity (new equivalent). This must be initialised later using init();
463 static CPlayerInfos *create() { return _PlayerAllocator.allocate(); }
465 /// Removes an entity (delete equivalent).
466 static void remove(CPlayerInfos *player) { _PlayerAllocator.freeBlock(player); }
468 private:
470 /// Static cell allocator
471 static NLMISC::CBlockMemory<CPlayerInfos> _PlayerAllocator;
478 #endif // NL_WORLD_ENTITY_H
480 /* End of world_entity.h */