Files
mir_server/server/LogicServer/scene/FuBenManager.cpp

778 lines
18 KiB
C++
Raw Normal View History

2025-01-09 17:45:40 +08:00
#include "StdAfx.h"
#include "FuBenManager.h"
#include "../base/Container.hpp"
CFuBenHandleMgr* CFuBenManager::m_FuBenMgr; //
SceneHandleMgr* CFuBenManager::m_SceneMgr;
CFuBenManager::RefreshPara CFuBenManager::m_RefreshPara;
EntityVector* CFuBenManager::m_pVisibleList;
//FubenHandleList::LinkNodeMgr* FubenHandleList::g_LinkNodeMgr;
CFuBenManager::CFuBenManager(void)
{
ZeroMemory(m_anFubenCount, sizeof(m_anFubenCount));
m_vMuiltyFbMap.clear();
}
VOID CFuBenManager::Destroy()
{
// 删除动态FB场景
#ifdef _USE_TRY_CATCH
#ifdef WIN32
__try
#endif
#endif
{
CLinkedNode<CFuBen*> *pNode;
CLinkedListIterator<CFuBen*> it(m_vAllFbList);
for (pNode = it.first(); pNode; pNode = it.next())
{
CFuBen* pFb = pNode->m_Data;
if (pFb)
{
pFb->ExitAllActor();
m_FuBenMgr->Release(pFb->GetHandle());//关闭副本,所有玩家会先退出副本
it.remove(pNode);
}
}
// 删除静态FB场景
for(int i = 0; i < m_vStaticFbList.count(); i++)
{
CFuBen* pFb = m_vStaticFbList[i];
if (pFb)
{
m_FuBenMgr->Release(pFb->GetHandle());//里面会执行副本的析构函数
}
}
m_vStaticFbList.clear();
// 删除预创建的动态FB暂时还未用到的动态副本
for (INT_PTR i = 0; i < m_FreeFbList.count(); i++)
{
FUBENVECTOR* pFbList = m_FreeFbList[i];
if (pFbList)
{
for(int j = 0; j < pFbList->count(); j++)
{
CFuBen* pFb = (*pFbList)[j];
if (pFb)
{
m_FuBenMgr->Release(pFb->GetHandle());//里面会执行副本的析构函数
}
}
pFbList->clear();
delete pFbList;
}
}
m_FreeFbList.clear();
// 删除地图数据
for(int i = 0; i < m_vMapDataList.count(); i++)
{
MAPDATA* md = m_vMapDataList[i];
if(md) {
delete md->pMapData;
delete md;
}
}
m_vMapDataList.clear();
}
#ifdef _USE_TRY_CATCH
#ifdef WIN32
__except(CustomExceptHandler(GetExceptionInformation()))
{
}
#endif
#endif
}
CFuBenManager::~CFuBenManager(void)
{
Destroy();
}
CFuBen* CFuBenManager::CreateFuBen(int nFbId)
{
// 验证FBId的有效性
if ((nFbId < 0) || (nFbId >= m_vStaticFbList.count()))
{
return NULL;
}
// 若为多人副本,则先看看是否已生成
if (m_vStaticFbList[nFbId]->GetConfig()->nFbEnterType == 2)
{
if(m_vMuiltyFbMap.find(nFbId) != m_vMuiltyFbMap.end())
return m_vMuiltyFbMap[nFbId];
}
CFuBen* newFb = NULL;
#ifndef REUSEFB
newFb = AllocNewFb(nFbId);
#else
// 看是否有空闲的副本
FUBENVECTOR* pList = m_FreeFbList[nFbId];
if (pList && pList->count() > 0)
{
newFb = (*pList)[pList->count()-1];
pList->remove(pList->count()-1);
newFb->OnReuse();
newFb->SetFreeFlag(false);
}else
{
// 没有空闲副本创建一个新的Fb
newFb = AllocNewFb(nFbId);
}
#endif
m_vAllFbList.linkAtLast(newFb);
if(newFb)
{
if(GetLogicServer()->GetLocalClient())
{
}
// 若为多人副本,则记录
if (newFb->GetConfig()->nFbEnterType == 2)
{
m_vMuiltyFbMap[nFbId] = newFb;
}
// 创建副本事件
CScriptValueList paramList;
paramList << (int)CFubenSystem::enOnCreate;
paramList << (int)newFb->GetConfig()->nFbConfType;
paramList << (int)newFb->GetFbId();
paramList << (int)newFb->GetConfig()->nFbEnterType;
paramList << newFb;
if(!GetGlobalLogicEngine()->GetGlobalNpc()->GetScript().CallModule("FubenDispatcher","OnEvent", paramList, paramList, 1))
{
OutputMsg(rmError,"[FubenSystem] OnEvent OnCreate 错误副本ID=%d副本类型=%d !",newFb->GetFbId(),newFb->GetConfig()->nFbConfType);
}
}
return newFb;
}
VOID CFuBenManager::ReleaseFuBen(CFuBen* pFuBen)
{
// 常规副本不能这里关闭
if (!pFuBen->IsFb())
return;
// 动态副本关闭 -- 这里怎么没有加入到自由副本列表中,而是直接删除了??
CLinkedNode<CFuBen*> *pNode;
CLinkedListIterator<CFuBen*> it(m_vAllFbList);
for (pNode = it.first(); pNode; pNode = it.next())
{
CFuBen* pFbInList = pNode->m_Data;
if (pFbInList == pFuBen)
{
// 若为多人副本,则取消记录
if (pFuBen->GetConfig()->nFbEnterType == 2)
{
int nFbId = pFuBen->GetFbId();
if(m_vMuiltyFbMap.find(nFbId) != m_vMuiltyFbMap.end())
{
pFuBen->ExitAllActor();
m_vMuiltyFbMap.erase(m_vMuiltyFbMap.find(nFbId));
return;
}
}
//把所有玩家退出副本先
pFuBen->ExitAllActor();
m_FuBenMgr->Release(pFbInList->GetHandle());//里面会执行副本的析构函数
it.remove(pNode);
break;
}
}
}
INT_PTR CFuBenManager::ReloadNpcScript(LPCTSTR szSceneName,LPCTSTR szNpcName)
{
INT_PTR result = 0;
INT_PTR nCount = m_vStaticFbList.count();
if (m_vStaticFbList.count() > 0)
{
CFuBen* pFuBen = m_vStaticFbList[0];
if (pFuBen)
{
result += pFuBen->ReloadNpcScript(szSceneName,szNpcName);
}
}
CLinkedNode<CFuBen*> *pNode;
CLinkedListIterator<CFuBen*> it(m_vAllFbList);
for (pNode = it.first(); pNode; pNode = it.next())
{
CFuBen* pFuBen = pNode->m_Data;
if (pFuBen)
{
result += pFuBen->ReloadNpcScript(szSceneName,szNpcName);
}
}
//空闲的副本npc也要重置
for (INT_PTR i = 0; i < m_FreeFbList.count(); i++)
{
FUBENVECTOR* pFbList = m_FreeFbList[i];
if (pFbList)
{
for(int j = 0; j < pFbList->count(); j++)
{
CFuBen* pFuBen = (*pFbList)[j];
if (pFuBen)
{
result += pFuBen->ReloadNpcScript(szSceneName,szNpcName);
}
}
}
}
return result;
}
void CFuBenManager::ResetFbRefresh()
{
m_RefreshPara.setFB(NULL);
m_RefTimer.SetNextHitTime(0);
}
void CFuBenManager::TraceRefreshPos()
{
char * pFbName="static";
int nFbId= -1;
if(CFuBenManager::m_RefreshPara.pFuben && CFuBenManager::m_RefreshPara.pFuben->GetConfig())
{
pFbName= "Fuben";
nFbId = (int)CFuBenManager::m_RefreshPara.pFuben->GetFbId();
}
TICKCOUNT nCurrentTick = _getTickCount(); //
TICKCOUNT nNextTick =m_RefTimer.GetNextTime();
int nDis =(int)( nNextTick - nCurrentTick);
if(nDis <0)
{
nDis =0;
}
int nScenePos = m_RefreshPara.nScenePos;
int nMonsterPos = m_RefreshPara.nRefreshPos;
OutputMsg(rmNormal,"Current Fb=%s,fbid=%d,dis= %d,scenePos=%d,monsterPos=%d",pFbName,nFbId,nDis,nScenePos,nMonsterPos);
}
//调试场景的信息
void CFuBenManager::Trace()
{
INT_PTR nCount = m_vStaticFbList.count();
CFuBen* pFuBen = m_vStaticFbList[0];
TraceRefreshPos();
for(INT_PTR i=0; i<m_vStaticFbList.count(); i++ )
{
CFuBen* pFuBen = m_vStaticFbList[i];
if(pFuBen)
{
pFuBen->Trace();
}
}
CLinkedNode<CFuBen*> *pNode;
CLinkedListIterator<CFuBen*> it(m_vAllFbList);
for (pNode = it.first(); pNode; pNode = it.next())
{
CFuBen* pFuBen = pNode->m_Data;
if(pFuBen)
{
pFuBen->Trace();
}
}
}
VOID CFuBenManager::RunOne()
{
DECLARE_TIME_PROF("CFuBenManager::RunOne");
SF_TIME_CHECK(); //检测性能
//执行每个副本的runone
TICKCOUNT nStartTick = _getTickCount(); //自行开始
if (!m_RefTimer.CheckAndSet(nStartTick))
return;
TICKCOUNT nLoopLimit = GetLoopTickLimit();
INT_PTR nCount = m_vStaticFbList.count();
if (nCount > 0)
{
CFuBen* pFuBen = m_vStaticFbList[0];
//找到上次执行到的副本
if ( pFuBen->RunOne() )
{
//SetLoopTickCount(_getTickCount() -nStartTick);
return;
}
}
//暂时屏蔽,外网可能有问题
/*
if(m_FreeFbTimer.CheckAndSet(nStartTick))
{
// 定时释放多余的空闲副本
for (INT_PTR i = 0; i < m_FreeFbList.count(); i++)
{
FUBENVECTOR* pFbList = m_FreeFbList[i];
if (pFbList && pFbList->count() > 2)
{
for(int j = pFbList->count() - 1; j >1 ; j--)
{
CFuBen* pFb = (*pFbList)[j];
if (pFb)
{
m_FuBenMgr->Release(pFb->GetHandle());//里面会执行副本的析构函数
pFbList->remove(j);
}
}
}
}
}
*/
// 处理动态副本的更新
CLinkedNode<CFuBen*> *pNode;
CLinkedListIterator<CFuBen*> it(m_vAllFbList);
for (pNode = it.first(); pNode; pNode = it.next())
{
CFuBen* pFuBen = pNode->m_Data;
int ret = pFuBen->RunOne();
if (ret == 2)
{
OutputMsg(rmTip,_T("release fuben!fubenid=%d,fhandle=%lld,freeFbCount=%d"),pFuBen->GetFbId(),pFuBen->GetHandle(),m_FreeFbList.count());
pFuBen->ExitAllActor();
#ifndef REUSEFB
m_FuBenMgr->Release(pFuBen->GetHandle());
#else
//放到空闲列表
bool boAdd = false;
if (m_FreeFbList.count() > pFuBen->GetFbId())
{
FUBENVECTOR* pList = m_FreeFbList[pFuBen->GetFbId()];
if (pList)
{
pList->add(pFuBen);
pFuBen->Reset();
pFuBen->SetFreeFlag(true);
boAdd = true;
if(m_vMuiltyFbMap.find(pFuBen->GetFbId()) != m_vMuiltyFbMap.end()) {
m_vMuiltyFbMap.erase(m_vMuiltyFbMap.find(pFuBen->GetFbId()));
return;
}
}
}
if (!boAdd)
{
m_FuBenMgr->Release(pFuBen->GetHandle());
}
#endif
it.remove(pNode);
}
else if (ret == 1 || _getTickCount() - nStartTick > nLoopLimit )
{
//SetLoopTickCount(_getTickCount() -nStartTick);
return;
}
}
m_RefreshPara.setFB(NULL);
//SetLoopTickCount(_getTickCount() -nStartTick);
}
bool CFuBenManager::EnterFuBen(CEntity * pEntity,CFuBen* pFuBen ,INT_PTR nScenceID,INT_PTR nPosX, INT_PTR nPosY,int nType, int nValue, int nParam )
{
if(pEntity ==NULL) return false;
if(pFuBen ==NULL)
{
pFuBen = m_vStaticFbList[0];
}
if(pFuBen ==NULL)
{
OutputMsg(rmWaning,_T("Enter fb fail for no such fb,nScenceID=%d"),nScenceID);
return false;
}
CFuBen* pDyFb = NULL;
CScene* pScene = NULL;
if(pEntity->GetType() == enActor)
{
pDyFb = ((CActor*)pEntity)->GetFuBen();
pScene = ((CActor*)pEntity)->GetScene();
}
return pFuBen->Enter(pEntity,nScenceID,nPosX,nPosY,0,0,nType, nValue, nParam,pScene, pDyFb);
//return pFuBen->Enter(pEntity,nScenceID,nPosX,nPosY,0,0,nType, nValue, nParam);
}
bool CFuBenManager::GetFbPtrBySceneName(LPCTSTR sName, CFuBen *& pRetFb, CScene *& pRetScene)
{
CScene * pScene =NULL;
pRetFb =NULL;
pRetScene =NULL;
for(INT_PTR i =0 ; i< m_vStaticFbList.count(); i++)
{
CFuBen *pFb = m_vStaticFbList[i];
if(pFb )
{
pScene = pFb->GetSceneByName(sName);
if(pScene)
{
pRetFb = m_vStaticFbList[i];
pRetScene = pScene;
return true;
}
}
}
return false;
}
bool CFuBenManager::GetFbPtrBySceneId( unsigned int nSceneID, CFuBen *& pRetFb, CScene *& pRetScene)
{
CScene * pScene =NULL;
pRetFb =NULL;
pRetScene =NULL;
for(INT_PTR i =0 ; i< m_vStaticFbList.count(); i++)
{
CFuBen *pFb = m_vStaticFbList[i];
if(pFb )
{
pScene = pFb->GetScene(nSceneID);
if(!pScene)
{
continue;
}
pRetFb = m_vStaticFbList[i];
pRetScene = pScene;
return true;
}
}
return false;
}
VOID CFuBenManager::AddStaticFuBen(CFuBen* pFb)
{
//Assert(pFb);
m_vStaticFbList.add(pFb);
}
bool CFuBenManager::GetFbPtrBySceneId( unsigned int nFbId, int nSceneID, CFuBen *& pRetFb, CScene *& pRetScene)
{
CScene * pScene =NULL;
pRetFb =NULL;
pRetScene =NULL;
CFuBen *pFb = NULL;
// 验证FBId的有效性
if (nFbId >= m_vStaticFbList.count())
{
return false;
}
if (m_vStaticFbList[nFbId]->GetConfig()->nFbEnterType == 2)
{
if(m_vMuiltyFbMap.find(nFbId) != m_vMuiltyFbMap.end())
{
pFb = m_vMuiltyFbMap[nFbId];
pScene = pFb->GetScene(nSceneID);
}
}
if(!pFb)
{
for(INT_PTR i =0 ; i< m_vStaticFbList.count(); i++)
{
pFb = m_vStaticFbList[i];
if(pFb) {
pScene = pFb->GetScene(nSceneID);
if(pScene)
break;
}
}
}
if(!pFb && !pScene ) return false;
pRetFb = pFb;
pRetScene = pScene;
return true;
}
CAbstractMap* CFuBenManager::GetMapData(const char* szFileName)
{
MAPDATA* data = NULL;
for(int i = 0; i < m_vMapDataList.count(); i++)
{
data = m_vMapDataList[i];
if (data && strcmp(szFileName,data->szFileName) == 0)
{
return data->pMapData;
}
}
//暂时没有数据,读入
data = new MAPDATA();
_asncpytA(data->szFileName,szFileName);
data->pMapData = new CAbstractMap();
data->pMapData->LoadFromFile(szFileName);
m_vMapDataList.add(data);
return data->pMapData;
}
bool CFuBenManager::GetVisibleList(CEntity * pEntity,EntityVector& vVisibleList,int nLeft,int nRight,int nUp,int nDown)
{
//根据实体的场景handle取得场景
//const ENTITYPOS& Pos = pEntity->GetPosInfo();
//CScene* pScene = Pos.pScene;//m_SceneMgr->GetDataPtr(Pos.nSceneHandler);
CScene* pScene = pEntity->GetScene();
if (pScene != NULL)
{
return pScene->GetVisibleList(pEntity,vVisibleList,nLeft,nRight,nUp,nDown);
}
return false;
}
bool CFuBenManager::GetVisibleList(CEntity * pEntity,CObserverEntityList& vVisibleList,int nLeft,int nRight,int nUp,int nDown, bool *pbActorInVisibleList)
{
//根据实体的场景handle取得场景
const ENTITYPOS& Pos = pEntity->GetPosInfo();
CScene* pScene = Pos.pScene;//m_SceneMgr->GetDataPtr(Pos.nSceneHandler);
if (pScene != NULL)
{
int nPosX,nPosY;
pEntity->GetPosition(nPosX,nPosY);
return pScene->GetVisibleList(nPosX, nPosY,vVisibleList,nLeft,nRight,nUp,nDown,pbActorInVisibleList);
}
return false;
}
bool CFuBenManager::GetSeqVisibleList(CEntity * pEntity, SequenceEntityList& visibleList,int nLeft,int nRight,int nUp,int nDown)
{
if (!pEntity)
return false;
int nPosX,nPosY;
pEntity->GetPosition(nPosX,nPosY);
//根据实体的场景handle取得场景
const ENTITYPOS& Pos = pEntity->GetPosInfo();
CScene* pScene = Pos.pScene;//m_SceneMgr->GetDataPtr(Pos.nSceneHandler);
if (pScene != NULL)
{
return pScene->GetSeqVisibleList(nPosX, nPosY, visibleList, nLeft,nRight,nUp,nDown);
}
return false;
}
COMMONFUBENCONFIG* CFuBenManager::GetConfig(int nFbid)
{
if ((nFbid >= 0) && (nFbid < m_vStaticFbList.count()))
{
CFuBen *pFb = m_vStaticFbList[nFbid];
if(pFb )
{
return pFb->GetConfig();
}
}
return NULL;
}
int CFuBenManager::GetFbCountFromId( UINT nFbid,UINT* pList,size_t nBufSize )
{
int ret = 0;
CLinkedNode<CFuBen*> *pNode;
CLinkedListIterator<CFuBen*> it(m_vAllFbList);
for (pNode = it.first(); pNode; pNode = it.next())
{
CFuBen* pFbInList = pNode->m_Data;
if (pFbInList->GetConfig()->nFbId == nFbid)
{
pList[ret++] = pFbInList->GetHandle();
}
}
return ret;
}
void CFuBenManager::RefreshMonster()
{
for (INT_PTR i = 0; i < m_vStaticFbList.count(); i++)
{
CFuBen* pFB = m_vStaticFbList[i];
if(pFB) {
pFB->RefreshMonster();
}
}
}
unsigned int CFuBenManager::TotalAllSceneMonsterCount()
{
unsigned int nTotalCount = 0;
for (INT_PTR i = 0; i < m_vStaticFbList.count(); i++)
{
CFuBen* pFB = m_vStaticFbList[i];
if(pFB) {
nTotalCount += pFB->TotalSceneMonsterCount();
}
}
return nTotalCount;
}
CFuBen* CFuBenManager::AllocNewFb( int nFbId,bool boRun )
{
// 验证FBId的有效性
if ((nFbId < 0) || (nFbId >= m_vStaticFbList.count()))
{
return NULL;
}
CFuBen* newFb = NULL;
CFuBen* fuben = m_vStaticFbList[nFbId];
//从内存管理中获取一个新的CFuBen
CFuBenHandle hHandle;
newFb = m_FuBenMgr->Acquire(hHandle);
fuben->Clone(*newFb,boRun);
newFb->SetHandle( hHandle );
if (nFbId < ArrayCount(m_anFubenCount))
m_anFubenCount[nFbId]++;
return newFb;
}
void CFuBenManager::Dump()
{
OutputMsg(rmNormal, _T("-------------------Dump Fuben Info-------------------"));
INT_PTR nCount = ArrayCount(m_anFubenCount);
for (INT_PTR i = 0; i < nCount; i++)
{
if (m_anFubenCount[i] > 0)
OutputMsg(rmNormal, _T("Fuben[%-2d] count:%-4d"), (int)i, m_anFubenCount[i]);
}
OutputMsg(rmNormal, _T("-------------------Dump Fuben Info-------------------"));
}
void CFuBenManager::DumpFbDataAlloc(wylib::stream::CBaseStream& stream)
{
if(m_SceneMgr)
{
TCHAR szBuff[MAX_PATH] = {0};
int FuBenSize = m_SceneMgr->GetUserDataSize();
_stprintf(szBuff, _T("m_SceneMgr:%d\r\n"),FuBenSize);
CBuffAllocStatHelper::WriteStrToStream(stream, szBuff);
}
if(m_FuBenMgr)
{
TCHAR szBuff[MAX_PATH] = {0};
int FuBenSize = m_FuBenMgr->GetUserDataSize();
_stprintf(szBuff, _T("m_FuBenMgr:%d\r\n"),FuBenSize);
CBuffAllocStatHelper::WriteStrToStream(stream, szBuff);
}
}
bool CFuBenManager::IsNeedShowFubenForm(int nFbId)
{
INT_PTR nCount = GetLogicServer()->GetDataProvider()->GetVocationConfig()->nDefualtFb.count();
if(nCount > 0)
{
for(INT_PTR i=0;i<nCount;i++)
{
CRESTEDEFAULTFb &tmpDefaultFb = GetLogicServer()->GetDataProvider()->GetVocationConfig()->nDefualtFb[i];
if(tmpDefaultFb.nFbId == nFbId)
{
return false;
}
}
}
return true;
}
void CFuBenManager::GetRandomCreatePos(int nToken,int& nScenceID,int& nPosX,int& nPosY)
{
INT_PTR nCount = GetLogicServer()->GetDataProvider()->GetVocationConfig()->nDefualtFb.count();
if(nCount <= 0)
{
return;
}
for(INT_PTR i=0;i<nCount;i++)
{
CRESTEDEFAULTFb &tmpDefaultFb = GetLogicServer()->GetDataProvider()->GetVocationConfig()->nDefualtFb[i];
if(tmpDefaultFb.nToken == nToken)
{
if(tmpDefaultFb.nPosCount > 0)
{
int nRandIndex = wrandvalue() % tmpDefaultFb.nPosCount;
if(nRandIndex >= 0 && nRandIndex < tmpDefaultFb.nPosCount && tmpDefaultFb.nCreatePos[nRandIndex].nScenceID > 0)
{
nScenceID = tmpDefaultFb.nCreatePos[nRandIndex].nScenceID;
nPosX = tmpDefaultFb.nCreatePos[nRandIndex].nPosX;
nPosY = tmpDefaultFb.nCreatePos[nRandIndex].nPosY;
}
}
break;
}
}
}
void CFuBenManager::CreateFreeFb()
{
#ifdef REUSEFB
m_FreeFbList.add(NULL);
for (INT_PTR i = 1; i < m_vStaticFbList.count(); i++)
{
CFuBen* pFb = m_vStaticFbList[i];//fb的id必须是连续的
if (pFb)
{
FUBENVECTOR* pList = new FUBENVECTOR();
m_FreeFbList.add(pList);
for (INT_PTR j = 0; j < 2; j++)
{
CFuBen* pFree = AllocNewFb(pFb->GetFbId(),false);
pList->add(pFree);
pFree->SetFreeFlag(true);
}
}
}
#endif
}
CFuBen* CFuBenHandleMgr::GetDataPtr( CFuBenHandle handle )
{
CFuBen* pfb = Inherited::GetDataPtr(handle);
if (pfb && !pfb->IsFree())
{
return pfb;
}
return NULL;
}
const CFuBen* CFuBenHandleMgr::GetDataPtr( CFuBenHandle handle ) const
{
const CFuBen* pfb = Inherited::GetDataPtr(handle);
if (pfb && !((CFuBen*)pfb)->IsFree())
{
return pfb;
}
return NULL;
}
CFuBenHandleMgr::CFuBenHandleMgr(LPCTSTR lpszDesc):Inherited(lpszDesc)
{
}