// 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 CL_NPC_ICON_H #define CL_NPC_ICON_H #include "nel/misc/types_nl.h" #include "game_share/entity_types.h" #include "game_share/msg_client_server.h" #include "nel/misc/cdb.h" #include "entity_cl.h" #include "interface_v3/view_radar.h" #include #include #include namespace NLMISC { class CBitMemStream; }; namespace NPC_ICON { // This enum maps TNPCMissionGiverState and adds some new values enum TNPCIconId { IconNone = AwaitingFirstData, IconNotAMissionGiver = NotAMissionGiver, IconListHasOutOfReachMissions = ListHasOutOfReachMissions, IconListHasAlreadyTakenMissions = ListHasAlreadyTakenMissions, IconListHasAvailableMission = ListHasAvailableMission, IconAutoHasUnavailableMissions = AutoHasUnavailableMissions, IconAutoHasAvailableMission = AutoHasAvailableMission, IconStepMission, NbNPCIcons }; }; using NLMISC::ICDBNode; /** * Description of a mission giver NPC. * Fed from the server on request by CNPCIconCache. */ class CNPCMissionGiverDesc { public: /// Constructor CNPCMissionGiverDesc() : _MissionGiverState(NPC_ICON::AwaitingFirstData), _LastUpdateTimestamp(0), _IsDescTransient(true), _HasChanged(false) {} // Current assignment operator: bitwise copy /// Return the current state NPC_ICON::TNPCMissionGiverState getState() const { return _MissionGiverState; } /// Return the time of last update (only valid if getState() != NPC_ICON::AwaitingFirstData) NLMISC::TGameCycle getLastUpdateTimestamp() const { return _LastUpdateTimestamp; } /// Return true if we are awaiting a description update bool isDescTransient() const { return _IsDescTransient; } /// Set as transient when about to be updated void setDescTransient() { _IsDescTransient = true; } /// Return true if state changed since the previous update bool hasChanged() const { return _HasChanged; } /// Set if state changed or not void setChanged(bool changed) { _HasChanged = changed; } /// Called on receival of update for this NPC. Return true if something has changed. bool updateMissionAvailabilityForThisChar(NPC_ICON::TNPCMissionGiverState state); /// Get debug dump std::string getDump() const; private: NPC_ICON::TNPCMissionGiverState _MissionGiverState; NLMISC::TGameCycle _LastUpdateTimestamp; bool _IsDescTransient; bool _HasChanged; }; typedef uint32 TNPCIconCacheKey; /** * NPC icon management system. * Tells which icons to display above NPCs, using data from either the server database * (for mission steps) or requesting and caching data from the server (for mission givers). */ class CNPCIconCache { public: /** * Description of an icon (main texture + optional overlay). * The spotId tells which small icon, and in which render layer, to display in the radar. */ class CNPCIconDesc { public: void init(const std::string& main, const std::string& over, CViewRadar::TRadarSpotId spotId=CViewRadar::Std) { _TextureMain=main; _TextureOver=over; _SpotId=spotId; } const std::string& getTextureMain() const { return _TextureMain; } const std::string& getTextureOver() const { return _TextureOver; } CViewRadar::TRadarSpotId getSpotId() const { return _SpotId; } private: std::string _TextureMain; std::string _TextureOver; CViewRadar::TRadarSpotId _SpotId; }; /// Accessor for singleton static CNPCIconCache& getInstance() { if (!_Instance) _Instance = new CNPCIconCache; return *_Instance; } /// Release singleton static void release(); /// Return key by entity (or 0 if entity if icon cache is N/A for this entity) inline static TNPCIconCacheKey entityToKey(const CEntityCL *entity) { return entity->npcAlias(); } /** * Return the filename of the icon to display for the specified NPC, using the following precedence: * 1. Icon for the case when the character has a mission step to do with the NPC (Step icon) * 2. Icon for the case when the character may or may not take a mission with the NPC (Auto or List icon) * 3. No mission related with this NPC (empty strings returned) */ const CNPCIconCache::CNPCIconDesc& getNPCIcon(const CEntityCL *entity, bool bypassEnabled = false); /// Init the system in either enabled or disabled state void init(bool enabled) { _Enabled = enabled; } /// Add DB observers void addObservers(); /// Remove DB observers void removeObservers(); /// Request an update about proposed missions of all qualifying npcs in vision, from the server void onEventForMissionAvailabilityForThisChar(); /// Update routine, to be called from main loop void update(); /// Enable or disable the system void setEnabled(bool b); /// Return the main enabled state bool enabled() const { return _Enabled; } /// Get debug dump std::string getDump() const; protected: class CMissionStartStopObserver : public ICDBNode::IPropertyObserver { public: virtual void update(ICDBNode* node); } MissionStartStopObserver; class CMissionNpcAliasObserver : public ICDBNode::IPropertyObserver { public: virtual void update(ICDBNode* node); } MissionNpcAliasObserver; class CMissionPrerequisitEventObserver : public ICDBNode::IPropertyObserver { public: virtual void update(ICDBNode* node); } MissionPrerequisitEventObserver; /// Request an update about proposed missions of the specified npc, from the server. void queryMissionGiverData(TNPCIconCacheKey npcIconCacheKey); friend struct commands_queryMissionGiverDataClass; /** Request an update about proposed missions on all qualifying visible NPCs, from the server. * If olderThan==0, all qualifying (i.e. that have missions) NPCs are included (and a request * is sent even for transient descriptions), whereas with a positive delay, only NPCs with * information old than Now-olderThan are included and transient descriptions are ignored. */ void queryAllVisibleMissionGiverData(NLMISC::TGameCycle olderThan); /** Update visible NPCs related to missions in progress, regarding * both missions actors (Step icon) and mission givers' proposed missions (Auto/List icon): * - when a mission is taken (started, new TITLE in database) * - when a mission is completed or failed (FINISHED changed in database) */ void onEventForMissionInProgress(); friend class CMissionStartStopObserver; /// Update visible NPCs related to missions in progress, regarding missions actors (Step icon) void onNpcAliasChangedInMissionGoals(); friend class CMissionNpcAliasObserver; /// Called on receival of update for this NPC. Return true if something has changed. bool onReceiveMissionAvailabilityForThisChar(TNPCIconCacheKey npcIconCacheKey, NPC_ICON::TNPCMissionGiverState state); friend void impulseSetNpcIconDesc(NLMISC::CBitMemStream &impulse); /// Called on receival of new timer delay void setMissionGiverTimer(NLMISC::TGameCycle delay); friend void impulseSetNpcIconTimer(NLMISC::CBitMemStream &impulse); /// Return true if the specified NPC is involved in current mission goals bool isNPCaCurrentGoal(TNPCIconCacheKey npcIconCacheKey) const; /// Store keys of current goals when current goals are changed void storeKeysOfCurrentGoals(); /// Called when data have been modified void refreshIconsOfScene(bool force = false); private: /// Private constructor (singleton) CNPCIconCache(); typedef std::map CMissionGiverMap; /// Map of mission giver descriptions CMissionGiverMap _MissionGivers; typedef std::vector CSmallKeyList; /// List of NPCs involved in current goals (typically, contains 0 to 3 elements) CSmallKeyList _KeysOfCurrentGoals; /// List of NPCs for which the description is to be requested at the current update CSmallKeyList _DescriptionsToRequest; /// Used by update() to do tick-update tasks NLMISC::TGameCycle _LastRequestTimestamp; /// Used by update() to do low frequency tasks NLMISC::TGameCycle _LastTimerUpdateTimestamp; /// Descriptions of icons for each case CNPCIconDesc _Icons[NPC_ICON::NbNPCIcons]; /// Main switch to disable the system bool _Enabled; // See in .cpp static NLMISC::TGameCycle _CacheRefreshTimerDelay; static NLMISC::TGameCycle _CatchallTimerPeriod; /// Instance of singleton static CNPCIconCache *_Instance; }; #endif // CL_NPC_ICON_H