📄 field.cpp
字号:
// Field.cpp: implementation of the Field class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Field.h"
#include <algorithm> ///< for set_difference()
#include <Macro.h>
#include <3DEngine/3DTerrain/3DTerrain.h>
#include <NPCInfoParser.h>
#include "Sector.h"
#include "FieldInfo.h"
#include "Player.h"
#include "Monster.h"
#include "ObjectFactory.h"
#include "GameServer.h"
#include "ObjectList.h"
#include "AITypes.h"
#include "ObjectGroup.h"
#include "RegenManager.h"
#include "TargetFinder.h"
#include "Map.h"
#include "MapObject.h"
#include "TriggerManager.h"
#include <SolarHashTable.h>
#include "ObjectGroupManager.h"
#include "EffectManager.h"
#include "PublicMath.h"
#include <Global.h>
#include "float.h"
#include "MapNpc.h"
Field::Field()
: m_pFieldInfo ( NULL ),
m_dwSectorSize ( 0 ),
m_dwSectorXNum ( 0 ),
m_dwSectorYNum ( 0 ),
m_dwTotalSectorNum ( 0 )
{
// pust_back()栏肺 持瘤 臼绰 版快俊 巩力!!!
m_vecTotalSector.reserve( MAX_RESERVED_SECTOR_OF_SECTOR_NUM );
m_pNPCList = new ObjectList;
m_pDeadNPCList = new ObjectList;
m_pMapObjectList = new ObjectList;
m_pRegenManager = new RegenManager( this );
m_pTriggerManager = new TriggerManager;
m_pObjectGroupManager = new ObjectGroupManager;
m_pEffectManager = new EffectManager( this );
m_pSectorGroupList = new SectorGroupList;
m_pObjectGroupManager->Init( ObjectGroupManager::MAX_DEFAULT_POOL_SIZE );
}
Field::~Field()
{
SAFE_DELETE( m_pNPCList );
SAFE_DELETE( m_pDeadNPCList );
SAFE_DELETE( m_pMapObjectList );
SAFE_DELETE( m_pRegenManager );
SAFE_DELETE( m_pTriggerManager );
SAFE_RELEASENDELETE( m_pObjectGroupManager );
SAFE_DELETE( m_pEffectManager );
SAFE_DELETE( m_pSectorGroupList );
}
BOOL Field::CheckMapVersion( DWORD dwCheckSum )
{
return m_pFieldInfo->CheckMapVersion( dwCheckSum );
}
VOID Field::Release( CMemoryPoolFactory<SectorGroup> * pSectorGroupPool, CMemoryPoolFactory<Sector> * pSectorPool )
{
RemoveAllNPC();
RemoveMapObjectAll();
m_pTriggerManager->Release();
m_pFieldInfo->Release(m_RoomIndex);
m_pFieldInfo = NULL;
m_pRegenManager->Release();
m_pEffectManager->Release();
// 冀磐客 冀磐弊缝阑 Release 茄促.
Sector* pSector; SectorGroup *pSectorGroup;
for( SECTORGROUP_ITERATOR it = m_pSectorGroupList->Begin(); it != m_pSectorGroupList->End(); ++it )
{
pSectorGroup = *it;
for( SECTOR_ITERATOR itr = pSectorGroup->Begin(); itr != pSectorGroup->End(); ++itr )
{
pSector = *itr;
pSector->Release();
pSectorPool->Free( pSector );
}
pSectorGroup->Release();
pSectorGroupPool->Free( pSectorGroup );
}
m_pSectorGroupList->Release();
m_vecTotalSector.clear();
}
VOID Field::Init( Map *pMap, FieldInfo * pFieldInfo, const TCHAR * pszGroupName,
CMemoryPoolFactory<SectorGroup> * pSectorGroupPool, CMemoryPoolFactory<Sector> * pSectorPool)
{
ASSERT( !m_pFieldInfo );
ASSERT( m_pNPCList->size() == 0 );
ASSERT( m_pDeadNPCList->size() == 0 );
ASSERT( m_pMapObjectList->size() == 0 );
m_pMap = pMap;
m_pFieldInfo = pFieldInfo;
m_dwTotalSectorNum = pFieldInfo->GetTotalSectorNum();
m_dwSectorXNum = pFieldInfo->GetSectorXNum();
m_dwSectorYNum = pFieldInfo->GetSectorYNum();
m_dwSectorSize = pFieldInfo->GetSectorSize();
m_nMaxPacketLevel = MAX_PACKET_LEVEL_INDEX;
m_RoomIndex = m_pFieldInfo->Init();
// SectorGroup 阑 积己秦辑 府胶飘俊 眠啊茄促.
BYTE byMarginX = 0, byMarginY = 0;
WORD wUnitSectorCount = m_pSectorGroupList->GetSectorUnitCount();
m_dwSectorXNum % wUnitSectorCount == 0 ? byMarginX = 0 : byMarginX = 1;
m_dwSectorYNum % wUnitSectorCount == 0 ? byMarginY = 0 : byMarginY = 1;
WORD wSectorGroupXNum = (WORD)(m_dwSectorXNum / wUnitSectorCount + byMarginX);
WORD wSectorGroupYNum = (WORD)(m_dwSectorYNum / wUnitSectorCount + byMarginY);
WORD wTotalSectorGroupNum = wSectorGroupXNum * wSectorGroupYNum;
m_pSectorGroupList->Init( wTotalSectorGroupNum );
m_pSectorGroupList->SetSectorGroupXNum( wSectorGroupXNum );
m_pSectorGroupList->SetSectorGroupYNum( wSectorGroupYNum );
SectorGroup *pSectorGroup = NULL;
for( WORD dwGroupIndex = 0; dwGroupIndex < wTotalSectorGroupNum; dwGroupIndex++ )
{
pSectorGroup = pSectorGroupPool->Alloc(); ASSERT( pSectorGroup != NULL );
pSectorGroup->Init( dwGroupIndex, wUnitSectorCount*wUnitSectorCount );
m_pSectorGroupList->AddSectorGroup( pSectorGroup );
}
// 冀磐甫 积己茄 饶 弊缝俊 楷搬茄促.
m_vecTotalSector.clear();
Sector *pSector = NULL; SectorInfo *pInfo = NULL;
for( DWORD dwSectorIndex = 0 ; dwSectorIndex < m_dwTotalSectorNum ; ++dwSectorIndex )
{
// 秦寸 冀磐狼 弊缝牢郸胶甫 备茄促.
DWORD dwGroupRow = dwSectorIndex / m_dwSectorXNum / wUnitSectorCount;
DWORD dwGroupColumn = ( dwSectorIndex % m_dwSectorXNum ) / wUnitSectorCount;
WORD wGroupIndex = (WORD)( dwGroupRow * wSectorGroupXNum + dwGroupColumn );
// 冀磐甫 积己茄促.
pInfo = m_pFieldInfo->GetSectorInfo( dwSectorIndex );
if( !pInfo ) continue;
pSector = pSectorPool->Alloc();
if( !pSector ) continue;
pSector->Init( dwSectorIndex, wGroupIndex );
// 冀磐 傈眉 府胶飘客 弊缝俊 阿阿 眠啊茄促.
m_vecTotalSector.push_back( pSector );
pSectorGroup = m_pSectorGroupList->GetGroup( wGroupIndex );
if( pSectorGroup ) pSectorGroup->AddSector( pSector );
}
AddMapObjectAll();
// 飘府芭 肺爹
if( pszGroupName[0] != '0' )
{
TriggerGroupInfo * pGroupInfo = GetFieldInfo()->GetTriggerGroupInfo( pszGroupName );
ASSERT( pGroupInfo && "飘府芭 弊缝捞 绝嚼聪促!!(World.txt曼绊)" );
m_pTriggerManager->Init( *pGroupInfo, this );
}
}
VOID Field::RemoveAllNPC()
{
ObjectFactory *pObjectFactory = ObjectFactory::Instance();
M_OBJECT_LIST_ITR it;
// NPC List
NPC* pNPC;
for( it = m_pNPCList->begin(); it != m_pNPCList->end(); ++it )
{
pNPC = (NPC*)(it->second);
pNPC->OnLeaveField();
pObjectFactory->FreeObject( pNPC );
}
m_pNPCList->RemoveAll();
for( it = m_pDeadNPCList->begin(); it != m_pDeadNPCList->end(); ++it )
{
pNPC = (NPC*)(it->second);
pNPC->OnLeaveField();
pObjectFactory->FreeObject( pNPC );
}
m_pDeadNPCList->RemoveAll();
}
VOID Field::AddMapObjectAll()
{
ASSERT( NULL != m_pFieldInfo );
// 甘坷宏璃飘 积己
util::SolarHashTable<MAPOBJECT_INFO *> * pMapObjectInfoTable = m_pFieldInfo->GetMapObjectInfoHashTable();
MAPOBJECT_INFO * pMapInfo = NULL;
pMapObjectInfoTable->SetFirst();
while( (pMapInfo = pMapObjectInfoTable->GetNext()) != NULL )
{
// 烙矫肺 阁胶磐内靛甫 悸泼秦辑 抛胶飘 秦夯促.
DWORD dwCode = 0;
BASE_NPCINFO* pBaseNPCInfo = NPCInfoParser::Instance()->GetMonsterInfo( dwCode );
// NPC 鸥涝狼 坷宏璃飘 积己
if( pBaseNPCInfo )
{
MapNpc * pMapNpc = static_cast<MapNpc *>(ObjectFactory::Instance()->AllocObject(MAPNPC_OBJECT));
pMapNpc->SetBaseInfo( pBaseNPCInfo );
pMapNpc->SetMapObjectInfo( pMapInfo );
// EnterField : 鞘靛俊 殿厘矫挪促.
EnterField( pMapNpc, &pMapInfo->wvPos );
}
// 老馆 甘 坷宏璃飘 积己
else
{
MapObject * pMapObject = static_cast<MapObject *>(ObjectFactory::Instance()->AllocObject(MAP_OBJECT));
pMapObject->SetObjectKey( pMapInfo->dwMapObjectID );
pMapObject->Init();
BOOL rt = m_pMapObjectList->Add( pMapObject );
ASSERT( rt );
}
}
}
BOOL Field::RemoveMapObject( const DWORD dwMapObjectID )
{
MapObject * pMapObject = NULL;
if( ( pMapObject = (MapObject *)m_pMapObjectList->Remove( dwMapObjectID ) ) == NULL )
{
return FALSE;
}
// 秦力
pMapObject->Release();
// 钱 馆券
ObjectFactory::Instance()->FreeObject( pMapObject );
return TRUE;
}
VOID Field::RemoveMapObjectAll()
{
M_OBJECT_LIST_ITR it;
for( it = m_pMapObjectList->begin(); it != m_pMapObjectList->end(); ++it )
{
MapObject * pMapObject = (MapObject *)(it->second);
pMapObject->Release();
ObjectFactory::Instance()->FreeObject( it->second );
}
m_pMapObjectList->clear();
}
MapObject * Field::FindMapObject( const DWORD dwObjectKey )
{
return (MapObject *)m_pMapObjectList->Find( dwObjectKey );
}
WzVector Field::GetRandomPosInAround( const WzVector * pOrgPos, INT iDist )
{
WzVector AroundPos = *pOrgPos;
RandomRangeVector( &AroundPos, iDist );
SetActiveRoom();
if( -1 == GetWorldBase()->x_pPathFinder->GetTileToStand( AroundPos ) )
return *pOrgPos;
return AroundPos;
}
WzVector Field::GetRandomStartingVector()
{
DWORD TileIndex = m_pFieldInfo->GetRandomStartingTileIndex();
int loop = 10;
WzVector wzVec = GetWorldBase()->GetRandomPosInTile( TileIndex );
SetActiveRoom();
while( -1 == GetWorldBase()->x_pPathFinder->GetTileToStand( wzVec ) && loop > 0 )
{
TileIndex = m_pFieldInfo->GetRandomStartingTileIndex();
wzVec = GetWorldBase()->GetRandomPosInTile( TileIndex );
--loop;
}
return wzVec;
}
VOID Field::GetAreaRandomVector( WzID id, WzVector & wzVec )
{
WzSpecialArea * pArea = m_pFieldInfo->GetAreaInfo( id );
//WzSpecialArea * pArea = m_pWorldBase->GetSpecialAreaByIndex( 0 );
ASSERT( pArea );
if( !pArea)
{
SUNLOG( eFULL_LOG, "[Field::GetAreaRandomVector] [AreaID:%u]康开捞 绝嚼聪促.", id );
wzVec = GetRandomStartingVector();
}
else
{
if( pArea->m_wbvRegion.m_eBvType == BVT_AABB )
{
wzVec.x = ( pArea->m_wbvRegion.m_aabb.m_wvMax.x + pArea->m_wbvRegion.m_aabb.m_wvMin.x ) / 2.f;
wzVec.y = ( pArea->m_wbvRegion.m_aabb.m_wvMax.y + pArea->m_wbvRegion.m_aabb.m_wvMin.y ) / 2.f;
wzVec.z = ( pArea->m_wbvRegion.m_aabb.m_wvMax.z );
}
else if( pArea->m_wbvRegion.m_eBvType == BVT_PATH_TILE_INDEX )
{
DWORD dwAreaTileCnt = pArea->m_wbvRegion.m_BvPathTileIndex.m_nCount;
DWORD * pdwTileIndex = pArea->m_wbvRegion.m_BvPathTileIndex.m_pdwData;
ASSERT(dwAreaTileCnt!=0);
int loop = 10;
DWORD dwSelectedTile = (WORD)(rand() % dwAreaTileCnt);
wzVec = GetWorldBase()->GetRandomPosInTile( pdwTileIndex[dwSelectedTile] );
SetActiveRoom();
while( -1 == GetWorldBase()->x_pPathFinder->GetTileToStand( wzVec ) && loop > 0 )
{
wzVec = GetWorldBase()->GetRandomPosInTile( pdwTileIndex[dwSelectedTile] );
--loop;
}
}
}
}
VOID Field::InitRegenManager( WORD MonsterType )
{
m_pRegenManager->Init( m_pMap->GetMapCode(), m_pFieldInfo->GetFieldCode(), MonsterType );
}
RC::ePACKET_SEND_RESULT Field::SendPacketAround( DWORD dwSectorIndex, MSG_BASE_FORWARD * pMsg, WORD wSize, DWORD dwMyObjKey )
{
if( !m_pFieldInfo ) return RC::RC_SEND_FAILED;
if( m_pFieldInfo->GetViewPort() )
{
Sector *pSector = GetSector( dwSectorIndex );
if( pSector )
{
pSector->SendPacketToSectorExceptMe( pMsg, wSize, dwMyObjKey );
}
/// 坷宏璃飘啊 加茄 冀磐狼 牢立 冀磐甸俊霸 菩哦 傈价
SectorInfo * pInfo = m_pFieldInfo->GetSectorInfo( dwSectorIndex );
if( !pInfo ) return RC::RC_SEND_FAILED;
POS pos = pInfo->GetNeighborSectorInfoList().GetFirstPos();
SectorInfo * pNextInfo = NULL;
while( (pNextInfo = pInfo->GetNeighborSectorInfoList().GetNextPos( pos )) != NULL )
{
pSector = GetSector( pNextInfo->GetSectorIndex() );
if( !pSector ) continue;
pSector->SendPacketToSector( pMsg, wSize );
}
}
else
{
return SendPacketToAll( pMsg, wSize, dwMyObjKey );
}
return RC::RC_SEND_SUCCESS;
}
RC::ePACKET_SEND_RESULT Field::SendPacketToAll( MSG_BASE_FORWARD * pMsg, WORD wSize, DWORD dwMyObjKey )
{
Sector *pSector; SectorGroup *pSectorGroup;
for( SECTORGROUP_ITERATOR it = m_pSectorGroupList->Begin(); it != m_pSectorGroupList->End(); ++it )
{
pSectorGroup = *it;
if( !pSectorGroup->GetReferenceCount() ) continue;
for( SECTOR_ITERATOR itr = pSectorGroup->Begin(); itr != pSectorGroup->End(); ++itr )
{
pSector = *itr;
pSector->SendPacketToSectorExceptMe( pMsg, wSize, dwMyObjKey );
}
}
return RC::RC_SEND_SUCCESS;
}
RC::ePACKET_SEND_RESULT Field::SendExPacketAround( DWORD dwSectorIndex, DWORD dwNumberOfMessages, BYTE **pMsg, WORD *pwSize, DWORD dwMyObjKey )
{
if( !m_pFieldInfo ) return RC::RC_SEND_FAILED;
if( m_pFieldInfo->GetViewPort() )
{
Sector *pSector = GetSector( dwSectorIndex );
if( pSector )
{
pSector->SendExPacketToSectorExceptMe( dwNumberOfMessages, pMsg, pwSize, dwMyObjKey );
}
/// 坷宏璃飘啊 加茄 冀磐狼 牢立 冀磐甸俊霸 菩哦 傈价
SectorInfo * pInfo = m_pFieldInfo->GetSectorInfo( dwSectorIndex );
if( !pInfo ) RC::RC_SEND_FAILED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -