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

304 lines
7.2 KiB
C++
Raw 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
/************************
实现场景中网格的管理和操作
***********************/
//class CLinkedNode<Entity*> EntityNode;
class CBaseEntityList;
class CEntity;
class CScene;
/*
因为内存非常巨大为了节省内存进行优化将x坐标一样的放一个列表这样1行的玩家在一个列表里
*/
#ifndef GRID_USE_STL_MAP
struct EntityHandlePos
{
EntityHandle hd; //实体的handle
WORD pos; //位置
};
typedef CBaseList<EntityHandlePos> EntityPosVector;
#else
struct HandleCmpter
{
bool operator()(const EntityHandle& _x, const EntityHandle& _y) const
{ return Uint64(_x) < Uint64(_y); }
};
typedef std::map<EntityHandle, WORD, HandleCmpter> EntityPosVector;
#endif
// 定义游戏中单个实体格子
class MapEntityGrid
{
public:
MapEntityGrid(){
//m_entitys.reserve(16);
}
~MapEntityGrid();
// 添加实体
void addEntity(EntityHandle handle, int posY){
#ifndef GRID_USE_STL_MAP
for (INT_PTR i = 0; i < m_entitys.count(); i++)
{
if (m_entitys[i].hd == handle)
{
return ;
}
}
EntityHandlePos pos;
pos.hd = handle;
pos.pos = (WORD)posY;
m_entitys.add(pos);
#else
assert(m_entitys.find(handle) == m_entitys.end());
m_entitys[handle] = posY;
#endif
}
void setEntityPos(EntityHandle handle,int posY)
{
#ifndef GRID_USE_STL_MAP
for (INT_PTR i = m_entitys.count() -1; i >-1 ; i--)
{
if (m_entitys[i].hd == handle)
{
m_entitys[i].pos=(WORD)posY;
return ;
}
}
#else
assert(m_entitys.find(handle) != m_entitys.end());
m_entitys[handle] = posY;
#endif
}
// 移除实体
void removeEntity(EntityHandle handle)
{
#ifndef GRID_USE_STL_MAP
for (INT_PTR i = m_entitys.count() -1; i >-1 ; i--)
{
if (m_entitys[i].hd == handle)
{
m_entitys.remove(i);
return ;
}
}
#else
//玩家初始化不成功,可能不在格子里
EntityPosVector::iterator it = m_entitys.find(handle);
//assert(m_entitys.find(handle) != m_entitys.end());
if(it != m_entitys.end())
{
m_entitys.erase(it);
}
#endif
}
int GetTypeEntityPosCount(int nType,int nPosY)
{
int nCount=0;
#ifndef GRID_USE_STL_MAP
for(INT_PTR i=0;i < m_entitys.count(); i++)
{
if((int)m_entitys[i].hd.GetType() == nType && m_entitys[i].pos == nPosY)
{
nCount ++;
}
}
#else
typedef typename EntityPosVector::iterator Iter;
Iter it;
Iter end = m_entitys.end();
for (it = m_entitys.begin(); it != end; it++)
{
if((int)(*it).first.GetType() == nType && (*it).second == nPosY)
nCount ++;
}
#endif
return nCount;
}
EntityPosVector m_entitys; // 格子中的实体列表
};
//typedef HandleMgr<CEntityList,CEntityListHandle > CEntityListMgr;
class CEntityGrid
{
friend class CScene;
friend class AStart;
friend class ASMapCell;
public:
CEntityGrid();
virtual ~CEntityGrid();
void SetScene(CScene* pScene) {m_pScene = pScene;}
//inline CEntityList* GetList(INT_PTR x,INT_PTR y);
MapEntityGrid* GetList(INT_PTR x);
/*inline VOID SetList(INT_PTR x,INT_PTR y,CEntityList* pList);*/
//释放资源
VOID Release();
//只清理怪物和玩家,以备重用
void Reset();
//释放一个list
VOID ReleaseList(CEntityList* el);
CEntityList* GetEntityList();
//重新设置网格的大小
VOID Init(int nRowCount,int nColCount);
/*
* Comments: 把一个实体添加到一个位置
* Param CEntity * pEntity: 实体的指针
* Param int nPosx: 位置x
* Param int nPosY: 位置y
* @Return int: 成功返回true否则返回false
*/
//bool AddEntity(CEntity * pEntity,INT_PTR nPosx,INT_PTR nPosY);
/*
* Comments:判断当前位置是否传送点,如果是则传送
* Param CEntity * pEntity:
* @Return void:
*/
void TelePort( CEntity * pEntity );
//判断是否可以通过传送门
bool CanPassPort( CEntity * pEntity,int nPassId);
/*
* Comments:判断能否把角色安排到网格中
* Param CEntity * pEntity:
* Param int nPosx:nposx会作为一个返回值因为有可能安排的位置和这个不同
* Param int nPosY:
* Param bool bShowErr: 是否输出错误
* @Return bool:
*/
bool CanAddEntity(CEntity * pEntity,INT_PTR& nX,INT_PTR& nY,bool bShowErr = true, bool bCanAlwaysEnter=false);
/*
* Comments:场景中删除一个实体(实体死亡或退出游戏或者去了其他场景)
* Param CEntity * pEntity:
* Param int nX:实体所在的位置
* Param int nY:
*/
void DeleteEntity(CEntity * pEntity);
//移动一个实体
int Move(CEntity * pEntity,INT_PTR nDir,INT_PTR nSpeed=1);
/*
* Comments:直接移动到某个坐标
* Param CEntity * pEntity:实体指针
* Param INT_PTR nNewX:要移动的位置
* Param INT_PTR nNewY:
* Param bool boNew:是否从其他场景跳转过来的
* @Return int:
*/
int MoveTo(CEntity * pEntity,INT_PTR nNewX,INT_PTR nNewY,bool boNew = false,bool bCanAlwaysEnter=false);
/*
* Comments:判断是否有穿人穿怪的限制
* Param INT_PTR nEntityType: 实体的类型
* Param INT_PTR x:坐标x
* Param INT_PTR y:坐标y
* @Return bool:如果有限制并且这个位置有人或怪返回false
*/
bool CanCross(INT_PTR nEntityType, INT_PTR x, INT_PTR y,bool bCanAlwaysEnter=false,bool bCanEnterFire = false);
/*
* Comments:根据旧的坐标和方向,速度计算
* Param INT_PTR & nX:
* Param INT_PTR & nY:
* Param BYTE nDir:
* Param int nSpeed:
* @Return VOID:
*/
static VOID NewPosition(INT_PTR& nX,INT_PTR& nY,INT_PTR nDir,INT_PTR nSpeed);
/*
* Comments:计算能不能移动到新位置
* Param CEntity* pEntity: 实体对象
* Param INT_PTR & nX:
* Param INT_PTR & nY:
* Param INT_PTR nDir:
* Param INT_PTR nSpeed:
* @Return bool:
*/
bool CanMoveTo(CEntity* pEntity, INT_PTR& nX,INT_PTR& nY,INT_PTR nDir,BYTE nSpeed);
/*
* Comments:判断这个网格能否站立
* Param CEntity* pEntity:实体对象
* Param INT_PTR x:x坐标
* Param INT_PTR y:y坐标
* @Return bool:
*/
bool CanMoveThisGrid(CEntity* pEntity,INT_PTR x ,INT_PTR y);
/*
* Comments:在一个点的周围寻找一个可以移动的点
* Param CEntity * pEntity:实体的指针
* Param CScene * pScene:场景的指针
* Param INT_PTR x: 位置x
* Param INT_PTR y:位置y
* Param INT_PTR & nResultX: 结果的位置x
* Param INT_PTR & nResultY:结果的位置y
* Param INT_PTR & nType:传进去的实体类型
* @Return bool:如果成功就返回true否则返回false
*/
static bool GetMoveablePoint(CEntity *pEntity,CScene * pScene, INT_PTR x,INT_PTR y,INT_PTR &nResultX,INT_PTR &nResultY,bool bCanAlwaysEnter = false,INT_PTR nType = 1);
//将区域下发给玩家
inline void SendAreaConfig(SCENEAREA* pArea,CActor *pActor);
protected:
/*
* Comments:角色移动时要做的判断,如果是跨过不同的区域,则要执行不同的操作
* Param CActor * pActor:
* @Return void:
*/
void CrossArea(CActor* pActor);
private:
/*
* Comments:判断指定的xy坐标是否能走动的点
* Param int x:x坐标
* Param int y:y坐标
* @Return bool:
*/
//bool CanMove(INT_PTR x,INT_PTR y);
private:
//网格的行数和列数
int m_nRow;
int m_nCol;
//一个二维数组保存链表的指针
//CEntityList** m_pGrid;
MapEntityGrid* m_pGrids; // 格子集合,用于一个维护一个场景中的所有小格子列表
CScene* m_pScene;
public:
//static CEntityListMgr* g_EntityListMgr; //实体链表的内存管理类,全局变量
};