// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef NL_WORLD_ENTITY_H #define NL_WORLD_ENTITY_H #include "nel/misc/types_nl.h" #include "nel/misc/block_memory.h" #include "nel/misc/debug.h" #include "nel/misc/time_nl.h" #include "nel/pacs/u_move_container.h" #include "nel/pacs/u_move_primitive.h" #include "gpm_utilities.h" #include "gpm_defs.h" #include "game_share/mirror_prop_value.h" #include "game_share/ryzom_mirror_properties.h" #include "server_share/msg_gpm_service.h" #include class CCell; class CPlayerInfos; class CWorldEntity; typedef std::list TWorldEntityList; struct CVisionEntry { CVisionEntry() { } CVisionEntry(CWorldEntity* e, uint32 m, uint32 d) : Entity(e), Mask(m), Distance(d) { } CWorldEntity* Entity; uint32 Mask; uint32 Distance; }; /** * World entity contained all properties positions in world for an entity * \author Alain Saffray * \author Nevrax France * \date 2002 */ class CWorldEntity { friend class NLMISC::CBlockMemory; public: typedef CSimpleSmartPointer CWorldEntitySmartPointer; enum TEntityType { Player = 0, Object, Trigger, AI, Unknown }; /* enum TVisionState // Enum of vision state for this entity { Ready = 0, // ready to use Checked, // in check Seen, // entity is seen by another }; */ public: NLMISC::CEntityId Id; // Id of entity TDataSetRow Index; CMirrorPropValue1DS X; // Coordinate X in world in unit CMirrorPropValue1DS Y; // Coordinate Y in world in unit CMirrorPropValue1DS Z; // Coordinate Z in world in unit CMirrorPropValue1DS LocalX; // Local Coordinate X in world in unit CMirrorPropValue1DS LocalY; // Local Coordinate X in world in unit CMirrorPropValue1DS LocalZ; // Local Coordinate X in world in unit CMirrorPropValue1DS Theta; // Heading in world CMirrorPropValue1DS Sheet; // Id sheet of entity CMirrorPropValue1DS Tick; // GameCycle of other properties CMirrorPropValue1DS Cell; // Current XY Cell where entity is CMirrorPropValue1DS VisionCounter; // Number of times this entity is seen by players uint32 PlayersSeeingMe; CWorldEntity* ClosestPlayer; CMirrorPropValue1DS WhoSeesMe; uint32 PatatEntryIndex; // The patat entry for the _PatatSubscribeManager CCell *CellPtr; // pointer on cell where entity is TWorldEntityList::iterator ListIterator; // Iterator on entity in world entity list TWorldEntityList::iterator PrimIterator; // Iterator on entity in prmitived entity list uint8 Continent; // index on the continent on which the player is located bool PosInitialised; // Pos was initialised by mirror bool UsePrimitive; // entity uses a primitive normally bool ForceUsePrimitive; // forces entity to use a primitive temporarily (mount, etc.) NLPACS::UMovePrimitive *Primitive; // Primitive for collision systeme (PACS) NLPACS::UMoveContainer *MoveContainer; // MoveContainer entity is in uint32 TickLock; CWorldEntitySmartPointer Previous; CWorldEntitySmartPointer Next; CPlayerInfos *PlayerInfos; // The player infos associated to this entity (if there is some) CWorldEntitySmartPointer Parent; // Which is entity we are in/on (ex: mount, ferry) std::vector Children; // Which are the child we contain CWorldEntitySmartPointer Control; // Which entity is controlling us (ex: rider, pilot...) bool ForceDontUsePrimitive; // forces entity not to use a primitive temporarily (mount, etc.) bool CheckMotion; bool HasVision; // Entity has vision std::vector Content; bool TempVisionState; // temporary flag for vision delta, telling if the entity is now visible bool TempControlInVision; // temporary flag for vision delta, telling if the controller entity (if any) is in vision bool TempParentInVision; // temporary flag for vision delta, telling if the parent (controlled) entity (if any) is in vision sint32 RefCounter; // Number of references on this entity -- used by smart pointer public: /** * destructor */ ~CWorldEntity(); /** * Init * \param id is entity's CEntityId */ void init( const NLMISC::CEntityId& id, const TDataSetRow &index ); /** * Display debug */ void display(NLMISC::CLog *log = NLMISC::InfoLog) const; /** * create primitive for fiche type entity * \param ficheId is sheet type Id of entity * \param pMoveContainer adress of the move container * \param worldImage numvber of the world image in which the primitive is to be inserted * \return pointer on PACS primitve */ void createPrimitive(NLPACS::UMoveContainer *pMoveContainer, uint8 worldImage); /** * Removes primitive allocated previously */ void removePrimitive(); /** * removes entity from the cell it is in */ //void removeFromCellAsEntity(); /** * removes object from the cell it is in */ //void removeFromCellAsObject(); /// Test if entity is linked in a cell bool isLinked() const { return CellPtr != NULL; } /// Get (const) CCell point in which entity is const CCell* getCell() const { return CellPtr; } /// Tests if entity uses a pacs primitive bool hasPrimitive() const { return Primitive != NULL && !ForceDontUsePrimitive; } /// local motion bool localMotion() const { return Parent != NULL; } /// has control ? bool hasControl() const { return Parent != NULL && Parent->Control == this; } /// is controlled ? bool isControlled() const { return Control != NULL; } /// has children bool hasChildren() const { return !Children.empty(); } /// remove from children void removeFromChildren(CWorldEntity *entity) { std::vector::iterator it; for (it=Children.begin(); it!=Children.end(); ++it) if ((CWorldEntity*)(*it) == entity) it = Children.erase(it); entity->Parent = NULL; Control = NULL; } /// get controlled CWorldEntity *getControlled() { if (!hasControl()) return NULL; CWorldEntity *parent = Parent; while (parent->hasControl()) parent = parent->Parent; return parent; } /// update local or global position void updatePosition(sint32 x, sint32 y, sint32 z, float theta, NLMISC::TGameCycle cycle, bool interior, bool water) { if (localMotion()) { LocalX = x; LocalY = y; LocalZ = z; setPosition(x + Parent->X(), y + Parent->Y(), z + Parent->Z(), true, interior, water); } else { setPosition(x, y, z, false, interior, water); } Tick = cycle; Theta = theta; // force position as valid PosInitialised = true; } /// update global position for local motion void updatePosition(bool interior, bool water) { if (localMotion()) { setPosition(LocalX() + Parent->X(), LocalY() + Parent->Y(), LocalZ() + Parent->Z(), true, interior, water); } } /// Set position void setPosition(sint32 x, sint32 y, sint32 z, bool local, bool interior, bool water) { X = x; Y = y; Z = (z&(~7)) + (local ? 1 : 0) + (interior ? 2 : 0) + (water ? 4 : 0); } /// update position using move primitive void updatePositionUsingMovePrimitive(uint wi); /// get Type of the entity TEntityType getType() const { return _Type; } private: /// Is in interior bool interior() const { return (Z()&2) != 0; } /// Type of the entity TEntityType _Type; public: /// Creates a new entity (new equivalent). This must be initialised later using init(); static CWorldEntity* create(); /// Removes an entity (delete equivalent). static void remove(CWorldEntity *entity); protected: /** * Default constructor, used because of CBlockMemory */ CWorldEntity() {} private: /// Static cell allocator static NLMISC::CBlockMemory _EntityAllocator; }; // typedef CWorldEntity::CWorldEntitySmartPointer CWorldEntityPtr; /// 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) typedef CObjectList TEntityList; /** * Player Infos : contains all information specific to players (like vision and original front end) * \author David Fleury * \author Nevrax France * \date 2002 */ class CPlayerInfos { friend class NLMISC::CBlockMemory; public: /// init void init(const NLMISC::CEntityId &id, NLNET::TServiceId feId, CWorldEntity *entity) { WhoICanSee = 0xffffffff; Next = NULL; Previous = NULL; ActivateSlot0 = false; DesactivateSlot0 = false; Slot0Active = false; uint i; for (i = MAX_SEEN_ENTITIES-1 ; i > 0; --i) FreeSlots.push_back( i ); for (i = 0 ; i < MAX_SEEN_ENTITIES ; ++i) Slots[i] = NULL; LastVisionTick = 0; _PlayerId = id; FeId = feId; Entity = entity; CheckSpeed = true; EnableVisionProcessing = true; } /// get playerId inline const NLMISC::CEntityId &getPlayerId() const { return _PlayerId; } /** * Display debug */ void display(NLMISC::CLog *log = NLMISC::InfoLog) const; private: /// the player Id NLMISC::CEntityId _PlayerId; /// default constructor CPlayerInfos() { } public: /// original front end Id NLNET::TServiceId FeId; /// front end datas TMapFrontEndData::iterator ItFrontEnd; /// iterator in the update player list TPlayerList::iterator ItUpdatePlayer; /// tick at last vision update NLMISC::TGameCycle LastVisionTick; /// Delay vision till cycle NLMISC::TGameCycle DelayVision; /// typedef CUnsafeConstantSizeStack TSlotStack; /// list of free slots for vision TSlotStack FreeSlots; /// The world entity for this player CWorldEntityPtr Entity; /// Previous player in list CPlayerInfos* Previous; /// Next player in list CPlayerInfos* Next; /// slots for this player CWorldEntityPtr Slots[MAX_SEEN_ENTITIES]; bool ActivateSlot0; bool DesactivateSlot0; bool Slot0Active; bool EnableVisionProcessing; bool CheckSpeed; /// Who I can see flag field uint32 WhoICanSee; #ifdef RECORD_LAST_PLAYER_POSITIONS /// Distance history std::deque< std::pair > DistanceHistory; #endif float meanSpeed() const { #ifdef RECORD_LAST_PLAYER_POSITIONS float dist = 0.0f; uint i; for (i=0; i+1 1 ? (dist/(DistanceHistory.size()-1)) : 0.0f; #else return 0.0f; #endif } struct CPlayerPos { NLMISC::TGameCycle AtTick; NLPACS::UGlobalPosition GPos; NLMISC::CVectorD Motion; float Theta; }; std::deque PosHistory; public: /// Creates a new entity (new equivalent). This must be initialised later using init(); static CPlayerInfos *create() { return _PlayerAllocator.allocate(); } /// Removes an entity (delete equivalent). static void remove(CPlayerInfos *player) { _PlayerAllocator.free(player); } private: /// Static cell allocator static NLMISC::CBlockMemory _PlayerAllocator; }; #endif // NL_WORLD_ENTITY_H /* End of world_entity.h */