#pragma once //#include "Container.h" #include #include #include /***************************************************************/ /* /* 实体管理器的概念 /* /* 是游戏的功能模块的管理器 /* /***************************************************************/ class StringComp { public: bool operator()(const char* const _Left, const char* const _Right) const { return strcmp(_Left, _Right) < 0; } }; //使用链表管理游戏世界里的实体 typedef Handle EntityIndex; // template class CWorldEntityList { public: CWorldEntityList(LPCTSTR lpszDesc,INT_PTR nRunTimeLinit =4) : m_entityMgr(lpszDesc) { m_runLimit = (int)nRunTimeLinit; #ifndef ENTITY_MANAGER_USE_STL_MAP m_interator.setList(m_list); m_cacheIter.setList(m_cacheList); #else m_interator = m_EntityMap.begin(); #endif } //释放一个handle inline void Release(EntityHandle handle) { m_entityMgr.Release(handle); } //添加一个实体 inline void Add( CEntity* pInputEntity) { #ifdef _DEBUG assert(pInputEntity->GetType() == T::GETTYPE()); #endif T* pEntity = (T* )pInputEntity; if(pEntity ==NULL) return; #ifndef ENTITY_MANAGER_USE_STL_MAP //设置实体的节点为为当前的节点,为了删除的时候高效地删除 pInputEntity->SetNode( (CList::NodeType *)m_list.linkAfter(pEntity)); #else m_EntityMap[Uint64(pEntity->GetHandle())] = pInputEntity; #endif } //删除一个实体 inline bool Destroy(CEntity * pInputEntity) { #ifdef _DEBUG assert(pInputEntity->GetType() == T::GETTYPE()); #endif T* pEntity = (T*)pInputEntity; if(pEntity ==NULL) return false; #ifndef ENTITY_MANAGER_USE_STL_MAP //CList::NodeType *pNode = (CList::NodeType *)pInputEntity->GetNode(); CLinkedNode *pNode = (CLinkedNode *)pInputEntity->GetNode(); pInputEntity->SetNode( NULL); if(pNode) { m_interator.remove(pNode); return true; } #else Iterator iter = m_EntityMap.find(pEntity->GetHandle()); if (iter != m_EntityMap.end()) { if (m_interator == iter) { m_EntityMap.erase(m_interator++); if (m_interator == m_EntityMap.end()) { m_interator = m_EntityMap.begin(); } } else m_EntityMap.erase(iter); return true; } #endif return false; } //清除 inline void Empty() { m_entityMgr.Empty(); #ifndef ENTITY_MANAGER_USE_STL_MAP m_list.clear(); m_cacheList.clear(); #else m_EntityMap.clear(); m_CacheMap.clear(); m_interator = m_EntityMap.end(); #endif } //缓存一个实体 inline void Cache(CEntity * pInputEntity) { #ifdef _DEBUG assert(pInputEntity->GetType() == T::GETTYPE()); #endif T* pEntity = (T*)pInputEntity; if(pEntity == NULL) return; #ifndef ENTITY_MANAGER_USE_STL_MAP if(CLinkedNode *pNode = (CLinkedNode*)pEntity->GetNode()) { m_interator.remove(pNode); } pEntity->SetNode((CList::NodeType *)m_cacheList.linkAfter(pEntity)); #else Iterator iter = m_EntityMap.find(pEntity->GetHandle()); if (iter != m_EntityMap.end()) { if (m_interator == iter) m_EntityMap.erase(m_interator++); else m_EntityMap.erase(iter); } m_CacheMap[pEntity->GetHandle()] = pEntity; #endif } //删除一个缓存实体 inline bool DestroyCache(CEntity * pInputEntity) { #ifdef _DEBUG assert(pInputEntity->GetType() == T::GETTYPE()); #endif T* pEntity = (T*)pInputEntity; if(pEntity == NULL) return false; #ifndef ENTITY_MANAGER_USE_STL_MAP if(CLinkedNode *pNode = (CLinkedNode *)pEntity->GetNode()) { m_cacheIter.remove(pNode); pEntity->SetNode(NULL); return true; } #else Iterator iter = m_CacheMap.find(pEntity->GetHandle()); if (iter != m_CacheMap.end()) { m_CacheMap.erase(iter); } #endif return false; } //解除缓存 inline void unCache(CEntity * pInputEntity) { #ifdef _DEBUG assert(pInputEntity->GetType() == T::GETTYPE()); #endif T* pEntity = (T*)pInputEntity; if(pEntity == NULL) return; #ifndef ENTITY_MANAGER_USE_STL_MAP if(CLinkedNode *pNode = (CLinkedNode*)pEntity->GetNode()) { m_cacheList.remove(pNode); } pEntity->SetNode((CList::NodeType *)m_list.linkAfter(pEntity)); #else Iterator iter = m_CacheMap.find(pEntity->GetHandle()); if (iter != m_CacheMap.end()) { m_CacheMap.erase(iter); } m_EntityMap[pEntity->GetHandle()] = pEntity; #endif } /* * Comments:一次逻辑调用 * Param TICKCOUNT tick:当前的tickCount * Param Uint64 nRunTimes:当前主循环运行了几轮 * @Return bool: 是否超时,如果超时返回true,否则返回false */ bool Run(TICKCOUNT tick) { SF_TIME_CHECK(); DECLARE_TIME_PROF("CWorldEntityList::Run"); TICKCOUNT nStart= _getTickCount(); T *pEntity; #ifndef ENTITY_MANAGER_USE_STL_MAP int nLoopLimit = m_list.count(); CLinkedNode *pNode; while ((pNode=m_interator.next()) && (nLoopLimit > 0)) { pEntity = *pNode; if(pEntity) { #ifdef _DEBUG assert(pEntity->GetType() == T::GETTYPE()); #endif pEntity->RunOne(tick); if( _getTickCount() - nStart > m_runLimit ) // { return true; } } --nLoopLimit; } #else int nLoopLimit = m_EntityMap.size(); //Iterator m_endIterator = m_EntityMap.end(); while ((m_interator != m_EntityMap.end()) && (nLoopLimit > 0)) { pEntity = (T*)(m_interator->second); if(pEntity) { #ifdef _DEBUG assert(pEntity->GetType() == T::GETTYPE()); #endif pEntity->RunOne(tick); if( _getTickCount() - nStart > m_runLimit ) // { if (m_interator != m_EntityMap.end()) ++m_interator; return true; } } if (m_interator != m_EntityMap.end()) ++m_interator; --nLoopLimit; } if (m_interator == m_EntityMap.end() || (nLoopLimit <= 0)) { m_interator = m_EntityMap.begin(); } #endif return false; } public: #ifndef ENTITY_MANAGER_USE_STL_MAP CList m_list; //实体的列表 CList m_cacheList; //实体的缓存列表 wylib::container::CLinkedListIterator m_interator; // 当前的迭代器 wylib::container::CLinkedListIterator m_cacheIter; // 缓存实体的迭代器 #else typedef typename std::map::iterator Iterator; typedef typename std::map::const_iterator ConstIterator; std::map m_EntityMap; //实体的列表 (handle,CEntity*) std::map m_CacheMap; //实体的缓存列表 Iterator m_interator; // 当前的迭代器 #endif HandleMgr m_entityMgr; //实体的管理器 int m_runLimit; //执行的最大的时间 }; typedef struct stCampTipData { LPVOID m_data; SIZE_T m_nLen; }CampTipData; template class CMonsterEntityList : public CWorldEntityList { public: CMonsterEntityList(LPCTSTR lpszDesc, INT_PTR nRunTimeLinit = 1, UINT_PTR nDivNum = 3) : CWorldEntityList(lpszDesc, nRunTimeLinit) { m_nDivNum = __max(nDivNum, 1); } bool Run(TICKCOUNT tick) { DECLARE_TIME_PROF("CMonsterEntityList::Run"); TICKCOUNT nStart= _getTickCount(); T *pEntity; #ifndef ENTITY_MANAGER_USE_STL_MAP UINT_PTR nMaxRunCount = this->m_list.count() / m_nDivNum; CLinkedNode *pNode; UINT_PTR nRunCount = 0; while (pNode = this->m_interator.next()) { pEntity = *pNode; if(pEntity) { #ifdef _DEBUG assert(pEntity->GetType() == T::GETTYPE()); #endif pEntity->RunOne(tick); nRunCount++; if (_getTickCount() - nStart > this->m_runLimit ) return true; if (nRunCount >= nMaxRunCount) return false; } } #else UINT_PTR nMaxRunCount = this->m_EntityMap.size() / m_nDivNum; nMaxRunCount = nMaxRunCount?nMaxRunCount:m_nDivNum; if (nMaxRunCount < m_nDivNum) nMaxRunCount = m_nDivNum; UINT_PTR nRunCount = 0; while (this->m_interator != this->m_EntityMap.end()) { pEntity = (T*)(this->m_interator->second); if(pEntity) { #ifdef _DEBUG assert(pEntity->GetType() == T::GETTYPE()); #endif pEntity->RunOne(tick); nRunCount++; if( _getTickCount() - nStart > this->m_runLimit ) return true; if (nRunCount >= nMaxRunCount) return false; } if (this->m_interator != this->m_EntityMap.end()) ++(this->m_interator); } if (this->m_interator == this->m_EntityMap.end()) { this->m_interator = this->m_EntityMap.begin(); } #endif return false; } inline void SetDivNum(UINT_PTR nDivNum) { if (m_nDivNum != nDivNum && nDivNum > 0) m_nDivNum = nDivNum; } private: UINT_PTR m_nDivNum; // 等分数。例如m_nDivNum=3表明将列表分为3等分,每次LogicRun的数目不超过总数量的1/3 }; class CEntityManager: public CComponent, public CSendPacketPool //实体管理器搞这个为了管理网络数据包,实现分时处理 { public: // 实体脚本回调句柄和句柄管理器类型定义 //typedef Handle EntityIndex; // typedef Handle EntitySCBHandle; typedef HandleMgr EntitySCBHdlMgr; typedef CWorldEntityList ActorMgr; typedef CMonsterEntityList MonsterMgr; typedef CMonsterEntityList NpcMgr; typedef CWorldEntityList CDropItemEntityMgr; //掉落物品 typedef CWorldEntityList TransferMgr; //传送门 typedef CMonsterEntityList PetMgr; // 宠物 typedef CWorldEntityList FireMgr; // 火的管理器 typedef CWorldEntityList HeroMgr; // 英雄的管理器 CEntityManager(); bool Initialize(); VOID Destroy(); void CloseAllActor(); //有玩家登陆了,将记录他的 inline void OnActorLogin(unsigned int nAccountId, unsigned int nActorId, EntityHandle handle) { m_actorIdList.insert(std::make_pair(nActorId, handle)); } inline void OnActorInit(const char* actorName, EntityHandle handle) { /*m_actorNameList.insert(std::make_pair(actorName, handle));*/ } void OnActorClosed(CActor* pActor); /* * Comments: db返回数据 * Param char * nCmd: 命令码 typedef enum tagDBRecvCmd { dcQuery=1, //查询数据 dcSave, //保存数据 dcLoadActor = 3, //加载用户认证信息 dcLoadQuest, //装置任务数据 dcSaveQuest, //保存用户的任务数据 dcLoadSkill, //装置技能数据 dcSaveSkill, //保持技能数据 }; * Param char * data: 数据指针 * Param SIZE_T size: 数据长度 * @Return void: */ void OnDbReturnData(INT_PTR nCmd,char * data,SIZE_T size); void OnDbNoticeFee(char * data,SIZE_T size); /* * Comments:会话服务器返回数据 * Param INT_PTR nCmd:命令id * Param char * data:数据内容 * Param SIZE_T size:数据大小 * @Return void: */ void OnSsReturnData(INT_PTR nCmd,char * data,SIZE_T size); /* * Comments: 接收到来自公共逻辑服务器转发的消息 * Param char * data: * Param SIZE_T size: * @Return void: * @Remark: */ void OnRecvCommServerLogicMessage(char *data, SIZE_T size); /* * Comments: 接收到来自其他逻辑服务器转发的消息 * Param char * data: * Param SIZE_T size: * @Return void: * @Remark: */ void OnRecvOtherLogicMessage(char *data, SIZE_T size); /* * Comments: 接收到来自公共服务器的数据 * Param INT_PTR nCmd: 消息号 * Param char * data: 数据内容 * Param SIZE_T size: 数据长度 * @Return void: * @Remark: 普通逻辑服务器调用此函数用于处理来自公共服务器的数据 */ void OnCommonServerRetData(INT_PTR nCmd, char *data, SIZE_T size); /* * Comments: 接收来自普通服务器的数据 * Param INT_PTR nCmd: 消息号 * Param char * data: 数据内容 * Param SIZE_T size: 数据长度 * @Return void: * @Remark: 公告逻辑服务器调用此函数接收来自普通服务器的数据 */ void OnLogicServerRetData(INT_PTR nCmd, char *data, SIZE_T size); /* * Comments: 创建一个实体 * Param INT_PTR nEntityType: 实体的类型 * Param EntityHandle & hHandle: 实体的handle * @Return CEntity *:实体的指针 */ CEntity * CreateEntity(int nEntityType,EntityHandle &hHandle); //创建一个实体,返回他的实体ID /* * Comments: 通过实体的handle销毁一个实体 * Param EntityHandle nEntityID: 实体的handle * Param bool bDelayDestroy: 延迟删除 * @Return bool:成功返回true,否则返回false */ bool DestroyEntity(EntityHandle nEntityID, bool bDelayDestroy = false) ; //销毁一个实体 bool CachePet(CActor* pMaster, CVector *pPetList, long long nExpireTime); bool UnCachePet(CActor* pMaster, CVector *pPetList, CScene* pScene); /* * Comments: 通过实体handle返回实体指针 * Param EntityHandle & hEntity: 实体 handle * @Return CEntity *:实体指针 */ CEntity * GetEntity(const EntityHandle &hEntity); /* * Comments: 通过玩家的名字查找指针 * Param char * name: 玩家名字 * @Return CActor *: 数据指针 */ inline CActor * GetActorPtrByName(const char * name) { if (!name) return NULL; /*ActorName2Hdl::iterator iter = m_actorNameList.find(name); if (iter != m_actorNameList.end()) return (CActor *)GetEntity(iter->second); return NULL;*/ CActor* pActor = NULL; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_actorMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pActor = *pNode; if(0== strcmp(name,pActor->GetEntityName()) ) { return pActor; } } #else ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); if(0== strcmp(name,pActor->GetEntityName()) ) { return pActor; } } #endif return NULL; } /* * Comments: 通过actorID找玩家的指针 * Param unsigned int nActorID: 玩家的角色id * @Return CActor *: 玩家的数据指针 */ inline CActor *GetEntityPtrByActorID(unsigned int nActorID) { ActorId2Hdl::iterator iter = m_actorIdList.find(nActorID); if (iter == m_actorIdList.end()) return NULL; return (CActor *)GetEntity(iter->second); } inline CActor *GetEntityPtrByAccountID(unsigned int nAccountID) { CActor *pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_actorMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pActor = *pNode; if( pActor->GetAccountID () ==nAccountID ) { return pActor; } } #else ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); if( pActor->GetAccountID () ==nAccountID ) { return pActor; } } #endif return NULL; } inline CActor *GetEntityPtrByAccountName(LPCSTR sAccount) { CActor *pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_actorMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pActor = *pNode; if( strcmp(pActor->GetAccount(),sAccount) == 0) { return pActor; } } #else ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); if( strcmp(pActor->GetAccount(),sAccount) == 0) { return pActor; } } #endif return NULL; } inline CMonster *GetMonsterPtrByEntityId(const unsigned int nMonsterId) { CMonster *pMonster; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_monsterMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pMonster = *pNode; if( nMonsterId == pMonster->GetProperty(PROP_ENTITY_ID) ) { return pMonster; } } #else ActorMgr::Iterator it = m_monsterMgr.m_EntityMap.begin(); for (; it != m_monsterMgr.m_EntityMap.end(); ++it) { pMonster = (CMonster*)(it->second); if( nMonsterId == pMonster->GetProperty(PROP_ENTITY_ID) ) { return pMonster; } } #endif return NULL; } VOID RunOne(); /* * Comments: 向所有在线的玩家广播 * Param char * pData:数据指针 * Param SIZE_T size:数据长度 * Param int nLevel: 广播的玩家最低限制等级 * @Return void: */ inline void BroadCast(char * pData,SIZE_T size, int nLevel = 0, int nCircle = 0) { CActor *pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_actorMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pActor = *pNode; if (pActor && pActor->IsInited() && pActor->CheckLevel(nLevel, nCircle)) { CActorPacket pack; CDataPacket &data = pActor->AllocPacket(pack); data.writeBuf(pData,size); pack.flush(); } } #else ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); if (pActor && pActor->IsInited() && pActor->CheckLevel(nLevel, nCircle)) { int nActorType = pActor->GetHandle().GetType(); if (nActorType == enActor) { if(pActor->OnGetIsTestSimulator() || pActor->OnGetIsSimulator() ) { continue; } } CActorPacket pack; CDataPacket &data = pActor->AllocPacket(pack); data.writeBuf(pData,size); pack.flush(); } } #endif } /* * Comments: 向所有在线的玩家广播 * Param char * pData:数据指针 * Param SIZE_T size:数据长度 * Param int nLevel: 广播的玩家最低限制等级 * @Return void: */ inline void BroadCastScene( char * pData,SIZE_T size, int nSceneId = 0, int nLevel = 0 ) { if( nSceneId == 0 ) { BroadCast(pData, size, nLevel); return; } CActor *pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_actorMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pActor = *pNode; if (pActor && pActor->IsInited() && pActor->CheckLevel(nLevel, 0) && pActor->GetSceneID() == nSceneId ) { CActorPacket pack; CDataPacket &data = pActor->AllocPacket(pack); data.writeBuf(pData,size); pack.flush(); } } #else ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); if (pActor && pActor->IsInited() && pActor->CheckLevel(nLevel, 0) && pActor->GetSceneID() == nSceneId ) { CActorPacket pack; CDataPacket &data = pActor->AllocPacket(pack); data.writeBuf(pData,size); pack.flush(); } } #endif } /* * Comments: 转发给武林盟主 * Param char * pData:数据指针 * Param SIZE_T size:数据长度 * Param int nLevel: 转发的玩家最低限制等级 * @Return void: */ inline void RetransmitToKungFuMaster(INT_PTR nZhenyinId, char * pData, SIZE_T size, int nLevel = 0) { /* CActor *pActor = GetKungFuMasterEntityPtr(); if (pActor && pActor->IsInited() && pActor->GetProperty(PROP_ACTOR_ZY) != nZhenyinId && pActor->GetProperty(PROP_CREATURE_LEVEL) >= nLevel && pActor->GetSocialMask(smIsWulinMaster)) { CActorPacket pack; CDataPacket &data = pActor->AllocPacket(pack); data.writeBuf(pData,size); pack.flush(); } */ } /* * Comments: 广播阵营提示 * Param const void * pData1: * Param SIZE_T size1: * Param const void * pData2: * Param SIZE_T size2: * Param const void * pData3: * Param SIZE_T size3: * @Return void: * @Remark: */ inline void BroadCampTipmsg(CampTipData data[3]) { CActor *pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_actorMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pActor = *pNode; if(pActor && pActor->IsInited()) { int nCampId = pActor->GetCampId(); if (nCampId > 0 && nCampId <= 3) { CampTipData* pData = &data[nCampId-1]; if (pData->m_data != NULL && pData->m_nLen > 0) { CActorPacket pack; CDataPacket &data = pActor->AllocPacket(pack); data.writeBuf(pData->m_data, pData->m_nLen); pack.flush(); } } } } #else ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); if(pActor && pActor->IsInited()) { int nCampId = pActor->GetCampId(); if (nCampId > 0 && nCampId <= 3) { CampTipData* pData = &data[nCampId-1]; if (pData->m_data != NULL && pData->m_nLen > 0) { CActorPacket pack; CDataPacket &data = pActor->AllocPacket(pack); data.writeBuf(pData->m_data, pData->m_nLen); pack.flush(); } } } } #endif } /* * Comments:获取在线玩家的id列表,好友模块需要 * Param CVector & IdList: * @Return void: */ inline void GetActorIdList(CVector& IdList) { IdList.clear(); CActor *pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_actorMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pActor = *pNode; IdList.add(pActor->GetId()); } #else ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); IdList.add(pActor->GetId()); } #endif } /* * Comments:获取在线玩家列表 * Param CVector & IdList: * @Return void: */ inline #ifndef ENTITY_MANAGER_USE_STL_MAP const CList #else const std::map& #endif getActorMap() { #ifndef ENTITY_MANAGER_USE_STL_MAP return m_actorMgr.m_list; #else return m_actorMgr.m_EntityMap; #endif } /* * Comments: 获取虚拟人的在线数量 * @Return INT_PTR:返回虚拟人在线人数的总数 */ inline INT_PTR GetOnlineSimulatorActorCount(INT_PTR& nTotalCount) { INT_PTR nActorCount = 0; CActor* pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP nTotalCount = m_actorMgr.m_list.count(); CList::Iterator iter(m_actorMgr.m_list); CList::NodeType* pNode; for (pNode = iter.first(); pNode; pNode = iter.next()) { pActor = *pNode; int nActorType = pActor->GetHandle().GetType(); if (nActorType == enActor) { if(!pActor->OnGetIsTestSimulator() && !pActor->OnGetIsSimulator() ) { continue;//不是虚拟人 } } if (pActor && pActor->GetGmLevel() <= 0) nActorCount++; } #else nTotalCount = m_actorMgr.m_EntityMap.size(); ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); int nActorType = pActor->GetHandle().GetType(); if (nActorType == enActor) { if(!pActor->OnGetIsTestSimulator() && !pActor->OnGetIsSimulator() ) { continue;//不是虚拟人 } } if (pActor && pActor->GetGmLevel() <= 0) nActorCount++; } #endif return nActorCount; } /* * Comments: 获取在线人数的数量 * @Return INT_PTR:返回在线人数的总数 */ inline INT_PTR GetOnlineActorCount(INT_PTR& nTotalCount) { INT_PTR nActorCount = 0; CActor* pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP nTotalCount = m_actorMgr.m_list.count(); CList::Iterator iter(m_actorMgr.m_list); CList::NodeType* pNode; for (pNode = iter.first(); pNode; pNode = iter.next()) { pActor = *pNode; if (pActor && pActor->GetGmLevel() <= 0) nActorCount++; } #else nTotalCount = m_actorMgr.m_EntityMap.size(); ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); if (pActor && pActor->GetGmLevel() <= 0) nActorCount++; } #endif return nActorCount; } inline void GetOnlineAcotrHandleList(CVector &actorList) { CActor *pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_actorMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pActor = *pNode; actorList.push(pActor->GetHandle()); } #else ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); actorList.push(pActor->GetHandle()); } #endif } int GetOnLineActorCountNoSame(); inline void GetOnlineAcotrPtrList(CVector &actorList, int nMinLevel = 0) { CActor *pActor; #ifndef ENTITY_MANAGER_USE_STL_MAP CList::Iterator it(m_actorMgr.m_list); CList::NodeType *pNode; for (pNode=it.first(); pNode; pNode = it.next()) { pActor = *pNode; if (nMinLevel > 0 && pActor->GetProperty(PROP_CREATURE_LEVEL) < nMinLevel) { continue; } actorList.add(pActor); } #else ActorMgr::Iterator it = m_actorMgr.m_EntityMap.begin(); for (; it != m_actorMgr.m_EntityMap.end(); ++it) { pActor = (CActor*)(it->second); if (nMinLevel > 0 && pActor->GetProperty(PROP_CREATURE_LEVEL) < nMinLevel) { continue; } actorList.add(pActor); } #endif } //获取广播数据的指针 inline char * GetBroadcastDataPtr() { return m_broadcastBuff; } /* * Comments: 全服发布广播 * Param char * sTipmsg: tipmsg的指针 * Param int nTipmsgType: 公告的显示类型,聊天栏,还是弹出框等 * @Return void: */ void BroadcastTipmsg(char * sTipmsg,int nTipmsgType =ttTipmsgWindow,int nLevel = 0); /* * Comments: 全服发布公告 * Param char * sTipmsg: tipmsg的指针 * Param int nTipmsgType: 公告的显示类型,聊天栏,还是弹出框等 * @Return void: */ void BroadNotice(char * sTipmsg, int nMsgType, int nLevel = 0); /* * Comments: 通过ID广播tipmsg * Param int nTipmsgID: 提示的ID * Param int nTipmsgType: 提示的内容 * @Return void: */ void BroadcastTipmsgWithID(int nTipmsgID, int nTipmsgType =ttTipmsgWindow); /* * Comments: 带参数全服广播 * Param int nTipmsgID: 提示的ID * Param int nTipmsgType: 提示的显示类型 * Param char * sParam1:参数1 * Param char * sParam2:参数2 * Param char * sParam3:参数3 * @Return void: */ void BroadTipmsgWithParams(int nTipmsgID,int nTipmsgType=ttTipmsgWindow,...); // 带参数全服广播 跨服--->原服 void BroadTipmsgWithParamsToCs(int nTipmsgID, int nTipmsgType, ...); /* * Comments:格式化系统提示的字符串,这个接口可以给外部使用 * Param int nTipmsgID: 系统提示的ID * Param int nTipmsgType: 系统提示的类型 * Param ...: 可变参数 * @Return INT_PTR: 返回数据长度 */ INT_PTR FormatTipmsg(int nTipmsgID,va_list &args,int nTipmsgType=ttTipmsgWindow); /* * Comments:更新怪物句柄,为怪物死亡立即刷新时实体复用适用。 * Param CEntity * pEntity: 怪物实体对象指针 * @Return void: */ void updateMonsterHandle(CEntity* pEntity); /* * Comments: 创建脚本事件参数对象 * Param EntitySCBHandle & handle: SCB句柄 * @Return ScriptCallbackParam*: */ ScriptCallbackParam* CreateScriptCallbackParam(EntitySCBHandle &handle); /* * Comments: 销毁脚本时间参数对象 * Param EntitySCBHandle & handle: * @Return void: */ void DestroyScriptCallbackParam(EntitySCBHandle &handle); /* * Comments: 获取脚本回调时间对象 * Param const EntitySCBHandle & handle: * @Return ScriptCallbackParam*: */ ScriptCallbackParam* GetScriptCallbackParam(const EntitySCBHandle &handle); //玩家向管理器申请一个网络包,用于缓存 CDataPacket * AllocDatapack() { if (m_freePacketList.count() <= 0) { allocSendPacketList(m_freePacketList,512); } CDataPacket* pTempData = m_freePacketList.pop();//得到一个空闲的Datapacket if(pTempData ) { pTempData->setPosition(0); } return pTempData; } //回收一个网络消息包 void FreeDataPack(CDataPacket * pData) { m_freePacketList.add(pData); //回收一个 } //获取一个实体一次循环最长需要的时间 inline int GetOneEntityTime() { return m_nOneEntityTime; } //设置一个实体的一次循环最长需要多长时间 inline void SetOneEntityTime(int nTime) { m_nOneEntityTime = nTime; } /* * Comments: 设置怪物LogicRun分组更新的等分数目 * Param UINT_PTR nDivNum: 分组更新的等分数目 * @Return void: * @Remark: */ inline void SetMonsterDivNum(UINT_PTR nDivNum) { m_monsterMgr.SetDivNum(nDivNum); } /* * Comments: 设置NPC LogicRun分组更新的等分数目 * Param UINT_PTR nDivNum: 分组更新的等分数目 * @Return void: * @Remark: */ inline void SetNpcDivNum(UINT_PTR nDivNum) { m_npcMgr.SetDivNum(nDivNum); } /* * Comments: 设置宠物LogicRun分组更新的等分数目 * Param UINT_PTR nDivNum: 分组更新的等分数目 * @Return void: * @Remark: */ inline void SetPetDivNum(UINT_PTR nDivNum) { m_petMgr.SetDivNum(nDivNum); } //统计实体的内存数据 void DumpEntityAllocData(wylib::stream::CBaseStream& stream); //统计实体的数量 int GetActorCount(){ return m_actorIdList.size();}; private: ActorMgr m_actorMgr; //玩家 MonsterMgr m_monsterMgr; //monster NpcMgr m_npcMgr; //NPC的管理器 CDropItemEntityMgr m_dropItemEntityMgr; //掉落管理器 TransferMgr m_transferMgr; //传送门的管理器 EntitySCBHdlMgr m_entitySCBHdlMgr; //实体脚本回调事件句柄管理器 PetMgr m_petMgr; //宠物管理器 FireMgr m_fireMgr; //火的管理器 HeroMgr m_heroMgr; //英雄管理器 CBaseList m_freePacketList ; //空闲的数据包列表 //游戏中怪物、npc等实体执行runone需要限定总时间 //这个变量记录当前执行到第几个实体的逻辑,则在下一个逻辑循环中从这个实体开始执行 //int m_nEntityRunPos; int m_nOneEntityTime; //一个实体处理的最大的时间 CVector m_waitRemoveEntityList; // 等待删除实体列表。在每次logicRun中删除 char m_broadcastBuff[4096]; //广播消息用的 Uint64 m_logicRunTimes; //逻辑循环调用了多少次 typedef std::map ActorId2Hdl; typedef std::map ActorName2Hdl; typedef std::map Monster2Dead; ActorId2Hdl m_actorIdList; ActorName2Hdl m_actorNameList; CTimer<1000> m_1secTimer; //1秒定时器 CTimer<5000> m_5secTimer; //5秒去检测这些火 CTimer<60000> m_1minsTimer; //每分钟发送怪的死亡次数 std::map > m_petCache; std::stack > m_petExpire; };