Files
mir_server/server/LogicServer/base/EntityManager.h
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

1189 lines
30 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
//#include "Container.h"
#include <map>
#include <stack>
#include <list>
/***************************************************************/
/*
/* 实体管理器的概念
/*
/* 是游戏的功能模块的管理器
/*
/***************************************************************/
class StringComp
{
public:
bool operator()(const char* const _Left, const char* const _Right) const
{
return strcmp(_Left, _Right) < 0;
}
};
//使用链表管理游戏世界里的实体
typedef Handle<unsigned int> EntityIndex; //
template<class T,int EntityCount =1024>
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<CEntity*>::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<T*>::NodeType *pNode = (CList<T*>::NodeType *)pInputEntity->GetNode();
CLinkedNode<T*> *pNode = (CLinkedNode<T*> *)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<T*> *pNode = (CLinkedNode<T*>*)pEntity->GetNode())
{
m_interator.remove(pNode);
}
pEntity->SetNode((CList<CEntity*>::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<T*> *pNode = (CLinkedNode<T*> *)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<T*> *pNode = (CLinkedNode<T*>*)pEntity->GetNode())
{
m_cacheList.remove(pNode);
}
pEntity->SetNode((CList<CEntity*>::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<T*> *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<T*> m_list; //实体的列表
CList<T*> m_cacheList; //实体的缓存列表
wylib::container::CLinkedListIterator<T*> m_interator; // 当前的迭代器
wylib::container::CLinkedListIterator<T*> m_cacheIter; // 缓存实体的迭代器
#else
typedef typename std::map<Uint64,CEntity*>::iterator Iterator;
typedef typename std::map<Uint64,CEntity*>::const_iterator ConstIterator;
std::map<Uint64,CEntity*> m_EntityMap; //实体的列表 handle,CEntity*
std::map<Uint64,CEntity*> m_CacheMap; //实体的缓存列表
Iterator m_interator; // 当前的迭代器
#endif
HandleMgr<T,EntityIndex,EntityCount> m_entityMgr; //实体的管理器
int m_runLimit; //执行的最大的时间
};
typedef struct stCampTipData
{
LPVOID m_data;
SIZE_T m_nLen;
}CampTipData;
template<typename T, int EntityCount = 1024>
class CMonsterEntityList : public CWorldEntityList<T, EntityCount>
{
public:
CMonsterEntityList(LPCTSTR lpszDesc, INT_PTR nRunTimeLinit = 1, UINT_PTR nDivNum = 3)
: CWorldEntityList<T, EntityCount>(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<T*> *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<int> EntityIndex; //
typedef Handle<unsigned int> EntitySCBHandle;
typedef HandleMgr<ScriptCallbackParam, EntitySCBHandle, 64> EntitySCBHdlMgr;
typedef CWorldEntityList<CActor,64> ActorMgr;
typedef CMonsterEntityList<CMonster> MonsterMgr;
typedef CMonsterEntityList<CNpc,64> NpcMgr;
typedef CWorldEntityList<CDropItemEntity,128> CDropItemEntityMgr; //掉落物品
typedef CWorldEntityList<CTransfer,64> TransferMgr; //传送门
typedef CMonsterEntityList<CPet, 128> PetMgr; // 宠物
typedef CWorldEntityList<CFire, 512> FireMgr; // 火的管理器
typedef CWorldEntityList<CHero, 64> 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<CPetSystem::PETDATA> *pPetList, long long nExpireTime);
bool UnCachePet(CActor* pMaster, CVector<CPetSystem::PETDATA> *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<CActor*>::Iterator it(m_actorMgr.m_list);
CList<CActor*>::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<CActor*>::Iterator it(m_actorMgr.m_list);
CList<CActor*>::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<CActor*>::Iterator it(m_actorMgr.m_list);
CList<CActor*>::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<CMonster*>::Iterator it(m_monsterMgr.m_list);
CList<CMonster*>::NodeType *pNode;
for (pNode=it.first(); pNode; pNode = it.next())
{
pMonster = *pNode;
if( nMonsterId == pMonster->GetProperty<unsigned int>(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<unsigned int>(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<CActor*>::Iterator it(m_actorMgr.m_list);
CList<CActor*>::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<CActor*>::Iterator it(m_actorMgr.m_list);
CList<CActor*>::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<unsigned>(PROP_ACTOR_ZY) != nZhenyinId
&& pActor->GetProperty<int>(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<CActor*>::Iterator it(m_actorMgr.m_list);
CList<CActor*>::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<int> & IdList:
* @Return void:
*/
inline void GetActorIdList(CVector<int>& IdList)
{
IdList.clear();
CActor *pActor;
#ifndef ENTITY_MANAGER_USE_STL_MAP
CList<CActor*>::Iterator it(m_actorMgr.m_list);
CList<CActor*>::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<int> & IdList:
* @Return void:
*/
inline
#ifndef ENTITY_MANAGER_USE_STL_MAP
const CList<CActor*>
#else
const std::map<Uint64,CEntity*>&
#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<CActor*>::Iterator iter(m_actorMgr.m_list);
CList<CActor*>::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<CActor*>::Iterator iter(m_actorMgr.m_list);
CList<CActor*>::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<EntityHandle> &actorList)
{
CActor *pActor;
#ifndef ENTITY_MANAGER_USE_STL_MAP
CList<CActor*>::Iterator it(m_actorMgr.m_list);
CList<CActor*>::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<void*> &actorList, int nMinLevel = 0)
{
CActor *pActor;
#ifndef ENTITY_MANAGER_USE_STL_MAP
CList<CActor*>::Iterator it(m_actorMgr.m_list);
CList<CActor*>::NodeType *pNode;
for (pNode=it.first(); pNode; pNode = it.next())
{
pActor = *pNode;
if (nMinLevel > 0 && pActor->GetProperty<int>(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<int>(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<CDataPacket*> m_freePacketList ; //空闲的数据包列表
//游戏中怪物、npc等实体执行runone需要限定总时间
//这个变量记录当前执行到第几个实体的逻辑,则在下一个逻辑循环中从这个实体开始执行
//int m_nEntityRunPos;
int m_nOneEntityTime; //一个实体处理的最大的时间
CVector<EntityHandle> m_waitRemoveEntityList; // 等待删除实体列表。在每次logicRun中删除
char m_broadcastBuff[4096]; //广播消息用的
Uint64 m_logicRunTimes; //逻辑循环调用了多少次
typedef std::map<unsigned int, EntityHandle> ActorId2Hdl;
typedef std::map<const char*, EntityHandle, StringComp> ActorName2Hdl;
typedef std::map<int, int> Monster2Dead;
ActorId2Hdl m_actorIdList;
ActorName2Hdl m_actorNameList;
CTimer<1000> m_1secTimer; //1秒定时器
CTimer<5000> m_5secTimer; //5秒去检测这些火
CTimer<60000> m_1minsTimer; //每分钟发送怪的死亡次数
std::map<int, CVector<CPetSystem::PETDATA> > m_petCache;
std::stack<std::pair<int,long long> > m_petExpire;
};