This commit is contained in:
aixianling
2025-01-09 17:45:40 +08:00
commit 5c9f1dae4a
3482 changed files with 1146531 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
#pragma once
#include<map>
/***************************************************************/
/*
/* 默认子系统
/* 对应子系统ID为0的系统主要处理一些逻辑基本消息
/***************************************************************/
class CDefaultSystem:
public CEntitySystem<enDefaultEntitySystemID>
{
public:
/*
* Comments:收到了网络数据包的处理函数
* Param INT_PTR nCmd:数据包的命令
* Param CDataPacketReader & pack:读取器
*/
virtual void OnRecvData(INT_PTR nCmd,CDataPacketReader & pack);
//定时执行
virtual void OnTimeRun(TICKCOUNT currentTick );
// 某坐标位置是否有(某类型)实体
bool HasEntity(unsigned int nEntityType, int nPosX, int nPosY);
bool HasEntity(int nPosX, int nPosY);
// 获取某位置某类型实体
CClientEntity* GetEntity(unsigned int nEntityType, int nPosX, int nPosY,bool include_guard = false);
// 获取其他玩家数据
inline CClientActor* GetOtherData(EntityHandle handle)
{
if (m_OtherActor.find(handle) != m_OtherActor.end())
{
return &m_OtherActor[handle];
}
return NULL;
}
// 获取怪物数据
inline int GetMonsterCount() { return m_Monster.size(); }
inline CClientMonster* GetMonster(EntityHandle handle)
{
if (m_Monster.find(handle) != m_Monster.end())
{
return &m_Monster[handle];
}
return NULL;
}
CClientMonster* GetMonster(bool include_guard = false);
CClientMonster* GetMonsterNot(EntityHandle handle,bool include_guard = false);
CClientMonster* GetNearestMonster(int dis = 14,bool include_guard = false);
CClientMonster* GetNearestMonsterNot(EntityHandle handle,int dis = 14,bool include_guard = false);
// 获取宠物数据
inline CClientPet* GetPet(EntityHandle handle)
{
if (m_Pets.find(handle) != m_Pets.end())
{
return &m_Pets[handle];
}
return NULL;
}
// 获取自己的位置
void GetPosition(int &x, int &y) const;
// 获取其他玩家位置
bool GetOtherPos(EntityHandle handle, int& nX, int& nY);
// 获取怪物位置
bool GetMonsterPos(EntityHandle handle, int& nX, int& nY);
// 获取宠物位置
bool GetPetPos(EntityHandle handle, int& nX, int& nY);
// 获取实体位置
bool GetEntityPos(EntityHandle handle, int& nX, int& nY);
// 请求移动
void Move(int nX, int nY, int nStep, int nDir);
//移动到目标点
void MoveTo(int nEndX, int nEndY, INT_PTR nStep=2);
// 请求复活
void ReqRelive();
//获取距离
int GetDistance(int nPosX,int nPosy);
//获取距离(横纵最长的)
unsigned int GetMaxDistance(int nPosX,int nPosy);
inline static INT_PTR GetDisSqare(INT_PTR nCurrentPosX,INT_PTR nCurrentPosY,INT_PTR nTargetX, INT_PTR nTargetY)
{
nCurrentPosX -= nTargetX;
nCurrentPosY -= nTargetY;
return nCurrentPosX* nCurrentPosX + nCurrentPosY* nCurrentPosY;
}
//计算移动的方向和步子
inline bool CalculateMoveParam(INT_PTR nStartX,INT_PTR nStartY,INT_PTR nEndX, INT_PTR nEndY, INT_PTR & nDir,INT_PTR &nStep,INT_PTR nMinDisSquare=0,INT_PTR nMaxDisSquare =0);
bool GetFanAvailablePos(INT_PTR nCurrentPosX,INT_PTR nCurrentPosY, INT_PTR &nDir,INT_PTR &nStep);
private:
//处理心跳包
void ProcessHeartBeat(CDataPacketReader & recvPack);
//处理玩家登陆失败
void ProcessLoginFail(CDataPacketReader & recvPack);
//处理主角创建包
void ProcessMainActorCreated(CDataPacketReader & recvPack);
//其他玩家进入视野
void ProcessActorAppear(CDataPacketReader &packet);
//怪物进入视野
void ProcessMonsterAppear(CDataPacketReader &packet);
//NPC进入视野
void ProcessNPCAppear(CDataPacketReader &packet);
//宠物出现在视野
void ProcessPetAppear(CDataPacketReader &packet);
//其他实体出现在视野
void ProcessOtherAppear(CDataPacketReader &packet);
// 处理实体消失
void ProcessEntityDisappear(CDataPacketReader &packet);
// 处理主玩家属性变更
void ProcessMainActorPropChange(CDataPacketReader &packet);
// 处理其他实体属性变更
void ProcessOtherEntityPropChange(CDataPacketReader &packet);
// 处理玩家进入场景
void ProcessPlayerEnterScene(CDataPacketReader& packet);
// 处理公共操作结果
void ProcessCommonOpResult(CDataPacketReader& packet);
// 处理其他实体移动
void ProcessOtherEntityMove(CDataPacketReader& packet);
// 处理重设主角位置
void ProcessResetMainActorPos(CDataPacketReader& packet);
// 处理实体死亡
void ProcessEntityDeath(CDataPacketReader&);
// 处理实体瞬间移动
void ProcessEntityInstatnceMove(CDataPacketReader& packet);
// 处理传送
void ProcessEntityTransport(CDataPacketReader& packet);
// 更新实体属性实现函数
void UpdateEntityPropImpl(CClientEntity* pEntity, CDataPacketReader& packet);
// 更新玩家坐标。用于客户端和服务器走路不同步的时候,根据服务器位置来调整
void SetPosition(const int nX, const int nY);
// 地图坐标实体映射关系维护方法
void AddMap(CClientEntity* pEntity, int nPosX, int nPosY);
void DelMap(CClientEntity* pEntity, int nPosX, int nPosY);
void ChgMap(CClientEntity* pEntity, int nOldPosX, int nOldPosY, int nPosX, int nPosY);
private:
std::map<EntityHandle,CClientActor> m_OtherActor; //其他玩家
std::map<EntityHandle,CClientMonster> m_Monster; //怪物
std::map<EntityHandle,CClientNPC> m_Npc; //NPC
std::map<EntityHandle,CClientPet> m_Pets; //宠物
std::map<EntityHandle,CClientTransfer> m_Transfer; //传送门
std::map<int, std::vector<CClientEntity*>> m_PosiEntityMap; //地图坐标实体映射
int m_nMapWidth;
TICKCOUNT m_heartbeart;
};

View File

@@ -0,0 +1,44 @@
#pragma once
/***************************************************************/
/*
/* 模拟器子系统基类
/* 模拟器的功能模块,比如组队子系统,技能子系统,继承这个基类去处理各种消息和逻辑
/***************************************************************/
template<int SUBSYSTEMID>
class CEntitySystem
{
public:
public:
CEntitySystem()
{
m_pClient =NULL;
}
/*
* Comments:收到了网络数据包的处理函数
* Param INT_PTR nCmd:数据包的命令
* Param CDataPacketReader & pack:读取器
* @Return void:
*/
virtual void OnRecvData(INT_PTR nCmd,CDataPacketReader & pack){};
//定时执行
virtual void OnTimeRun(TICKCOUNT currentTick ){}
//获取子系统的ID
inline int GetSystemId(){return SUBSYSTEMID;}
//初始化
void Init(CRobotClient * pClient){m_pClient =pClient;}
//进入游戏,收到了服务器发送的主角创建的包
virtual void OnEnterGame(){}
protected:
CRobotClient * m_pClient ; //用于发送数据包和接收数据包
};

View File

@@ -0,0 +1,103 @@
#include "stdafx.h"
CEquipSystem::EquipMessageHandler CEquipSystem::s_aHandler[] = {
&CEquipSystem::DefaultProcessHandler,
&CEquipSystem::ProcessTakeOnEquip,
&CEquipSystem::ProcessTakeOffEquip,
&CEquipSystem::ProcessInitEquip, // 初始化物品列表
};
void CEquipSystem::ProcessTakeOnEquip(CDataPacketReader& packet)
{
CUserItem::ItemSeries series;
packet >> series.llId;
CUserItem* pItem = m_pClient->GetLogicAgent().GetItemSystem().GetItem(series);
m_equipList.add(*pItem);
}
void CEquipSystem::ProcessTakeOffEquip(CDataPacketReader& packet)
{
CUserItem::ItemSeries series;
packet >> series.llId;
for (int i=0; i < m_equipList.count(); i++)
{
CUserItem& useItem = m_equipList[i];
if (useItem.series.llId == series.llId)
{
m_equipList.remove(i);
break;
}
}
}
void CEquipSystem::ProcessInitEquip(CDataPacketReader& packet)
{
//OutputMsg(rmNormal, _T("Recv Initialize EquipList"));
BYTE bCount = 0;
packet >> bCount;
CUserItem item;
for (INT_PTR i = 0; i < bCount; i++)
{
packet >> item;
m_equipList.add(item);
}
}
void CEquipSystem::OnRecvData(INT_PTR nCmd, CDataPacketReader& packet)
{
if (nCmd < 0 || nCmd >= ArrayCount(s_aHandler))
return;
return (this->*s_aHandler[nCmd])(packet);
}
void CEquipSystem::OnEnterGame()
{
RequestEquipList();
}
void CEquipSystem::RequestEquipList()
{
CDataPacket& pack = m_pClient->AllocProtoPacket();
pack << (BYTE)enEuipSystemID << (BYTE)cGetEquip;
m_pClient->FlushProtoPacket(pack);
}
void CEquipSystem::CheckAndTakeOnEquip(CUserItem& userItem)
{
// const CStdItem* pStdItem = GetRobotMgr()->GetGlobalConfig().GetItemConfig().GetStdItemConfig(userItem.wItemId);
// if (!pStdItem)
// {
// return;
// }
// for (int i =0; i < m_equipList.count(); i++)
// {
// CUserItem& useItem = m_equipList[i];
// const CStdItem* pStdEquip = GetRobotMgr()->GetGlobalConfig().GetItemConfig().GetStdItemConfig(userItem.wItemId);
// if (!pStdEquip ) continue;
// if (pStdEquip == pStdItem)
// {
// return;
// }
// if (pStdEquip->m_btType == pStdItem->m_btType)
// {
// if (pStdEquip->GetUseConditionValue(CStdItem::ItemUseCondition::ucLevel) > pStdItem->GetUseConditionValue(CStdItem::ItemUseCondition::ucLevel))
// {
// return;
// }
// else if (pStdEquip->GetUseConditionValue(CStdItem::ItemUseCondition::ucMinCircle) > pStdItem->GetUseConditionValue(CStdItem::ItemUseCondition::ucMinCircle))
// {
// return;
// }
// }
// }
// TakeOnEquip(userItem.series);
}
void CEquipSystem::TakeOnEquip(CUserItem::ItemSeries series)
{
CDataPacket& packet = m_pClient->AllocProtoPacket();
packet << (BYTE)enEuipSystemID << (BYTE)cTakeOnEquip;
packet << series.llId;
m_pClient->FlushProtoPacket(packet);
}

View File

@@ -0,0 +1,32 @@
#pragma once
class CEquipSystem : public CEntitySystem<enEuipSystemID>
{
public:
static const INT_PTR EquipmentCount = itMaxEquipPos;
void OnRecvData(INT_PTR nCmd, CDataPacketReader& packet);
void OnEnterGame();
void CheckAndTakeOnEquip(CUserItem& userItem);
private:
// 消息处理
void DefaultProcessHandler(CDataPacketReader&){}
void ProcessInitEquip(CDataPacketReader& packet);
void ProcessTakeOnEquip(CDataPacketReader& packet);
void ProcessTakeOffEquip(CDataPacketReader& packet);
// 请求物品列表
void RequestEquipList();
void TakeOnEquip(CUserItem::ItemSeries series);
private:
typedef void (CEquipSystem::*EquipMessageHandler)(CDataPacketReader& packet);
static EquipMessageHandler s_aHandler[];
CBaseList<CUserItem> m_equipList;
};

View File

@@ -0,0 +1,98 @@
#include "stdafx.h"
CItemSystem::ItemMessageHandler CItemSystem::s_aHandler[] = {
&CItemSystem::DefaultProcessHandler,
&CItemSystem::DelItem,
&CItemSystem::AddNewItem,
&CItemSystem::DefaultProcessHandler,
&CItemSystem::ProcessInitItems, // 初始化物品列表
};
void CItemSystem::ProcessInitItems(CDataPacketReader& packet)
{
OutputMsg(rmNormal, _T("Recv Initialize ItemList"));
WORD wCount = 0;
packet >> wCount;
CUserItem item;
for (INT_PTR i = 0; i < wCount; i++)
{
packet >> item;
m_itemList.add(item);
}
}
void CItemSystem::OnRecvData(INT_PTR nCmd, CDataPacketReader& packet)
{
if (nCmd < 0 || nCmd >= ArrayCount(s_aHandler))
return;
return (this->*s_aHandler[nCmd])(packet);
}
void CItemSystem::OnEnterGame()
{
RequestItemList();
}
void CItemSystem::RequestItemList()
{
}
CUserItem* CItemSystem::GetItem(CUserItem::ItemSeries series)
{
for (INT_PTR i = 0; i < m_itemList.count(); i++)
{
CUserItem* item = &m_itemList[i];
if (item->series.llId == series.llId)
{
return item;
}
}
return NULL;
}
void CItemSystem::DelItem(CDataPacketReader& packet)
{
CUserItem::ItemSeries series;
packet >> series.llId;
for (INT_PTR i = 0; i < m_itemList.count(); i++)
{
CUserItem& item = m_itemList[i];
if (item.series.llId == series.llId)
{
m_itemList.remove(i);
break;
}
}
}
void CItemSystem::UseItem(LONG64 nGuid, bool bIsHeroUse, int nParam )
{
CDataPacket& packet = m_pClient->AllocProtoPacket();
packet << (BYTE)enBagSystemID << (BYTE)enBagSystemcUseItem;
packet << nGuid << (BYTE)bIsHeroUse <<nParam;
m_pClient->FlushProtoPacket(packet);
}
void CItemSystem::AddNewItem(CDataPacketReader& packet)
{
// CUserItem userItem;
// packet >> userItem;
// m_itemList.add(userItem);
// const CStdItem* pStdItem = GetRobotMgr()->GetGlobalConfig().GetItemConfig().GetStdItemConfig(userItem.wItemId);
// if (pStdItem)
// {
// if (pStdItem->m_btType == Item::itFunctionItem)
// {
// UseItem(userItem.series.llId);
// #ifdef _DEBUG
// OutputMsg(rmNormal,"[%s] UseItem %s", m_pClient->GetActorName(),pStdItem->m_sName);
// #endif
// }
// else if (pStdItem->isEquipment())
// {
// m_pClient->GetLogicAgent().GetEquipSystem().CheckAndTakeOnEquip(userItem);
// }
// }
}

View File

@@ -0,0 +1,34 @@
#pragma once
class CItemSystem : public CEntitySystem<enBagSystemID>
{
public:
void OnRecvData(INT_PTR nCmd, CDataPacketReader& packet);
void OnEnterGame();
public:
CUserItem* GetItem(CUserItem::ItemSeries series);
private:
// 消息处理
void DefaultProcessHandler(CDataPacketReader&){}
void ProcessInitItems(CDataPacketReader& packet);
// 请求物品列表
void RequestItemList();
/*
* Comments:添加新物品
* Param CDataPacketReader & packet:
* @Return void:
*/
void AddNewItem(CDataPacketReader& packet);
void DelItem(CDataPacketReader& packet);
void UseItem(LONG64 nGuid, bool bIsHeroUse = false, int nParam = 0 );
private:
typedef void (CItemSystem::*ItemMessageHandler)(CDataPacketReader& packet);
static ItemMessageHandler s_aHandler[];
CBaseList<CUserItem> m_itemList;
};

View File

@@ -0,0 +1,3 @@
#include "stdafx.h"
char CUpdateMask::s_forbitUpdateMask[CUpdateMask::MAX_MASK_BYTE_COUNT];

View File

@@ -0,0 +1,151 @@
#pragma once
/*
** 本文件主要用于定义客户端同服务器之间的网络消息协议数据定义。
*/
#pragma pack(push, 1)
/*
enum ScriptSubSystemID
{
enScriptMiscSystem = 139,
enScriptTestSystem = 150,
};
*/
enum ScriptMiscSystemMsgID
{
enMisc_QuickTel = 7, // 速传
};
// 测试子系统消息定义
enum TestSystemMsgID
{
enTestSys_ReliveInPlace = 1, // 原地复活
enTestSys_EnterFuben = 2, // 进入副本
enTestSys_RequestEquips=3, // 请求装备
};
// 其他非玩家实体数据( TODELETE )
typedef struct tagNonActorPropData
{
EntityHandle handle; // 实体句柄
char szDecorateName[256]; // 修饰名称
WORD wPosX; // 实体坐标X
WORD wPosY; // 实体坐标Y
unsigned int wModelId; // 实体模型Id
BYTE ucDir; // 朝向
// 以下是怪物、宠物特有的数据
BYTE ucLevel; // 等级
unsigned int nHP; // HP
unsigned int nMP; // MP
unsigned int nMaxHP; // 最大HP
unsigned int nMaxMP; // 最大MP
WORD wMoveSpeed; // 移动速度实际上是移动一个格子需要的时间ms
WORD wAttackSpeed; // 攻击速度实际上是攻击时间间隔ms
unsigned int nStatus; // 实体状态
unsigned int nCreatureColor;
unsigned int nNameColor; // 名字颜色
BYTE ucAttackType; // 攻击类型和怪物类型。攻击类型占低4位怪物类型占高4位
// 以下还有Buff数据、效果Effect数据、怪物拥有者句柄、NPC功能分类Id等暂时未用到不做定义
}NonActorPropData;
// 其他玩家数据
typedef struct tagOtherActorPropData
{
EntityHandle handle; // 实体句柄
char szDecorateName[256]; // 修饰名称
WORD wPosX; // 实体坐标X
WORD wPosY; // 实体坐标Y
int nModelId; // 实体模型Id
unsigned int nHP; // HP
unsigned int nMP; // MP
unsigned int nMaxHP; // MaxHP
unsigned int nMaxMP; // MaxMP
WORD wMoveSpeed; // 移动速度
BYTE ucSex; // 性别
BYTE ucVocation; // 职业
WORD ucLevel; // 等级
unsigned int nCircle; //转数
int nWeaponAppear; // 武器外观
int nSwingAppear; //翅膀外观
int nSocialMask; //社会关系
WORD wIcon; // 图标
WORD nAttackSpeed; // 攻击速度
BYTE ucDir; // 朝向
unsigned int nStatus; // 状态掩码
unsigned int nRes1;
int nTeamId; // 队伍Id
BYTE ucCamp; // 阵营
unsigned int nHeadTitle; // 头衔
unsigned int nNameColor; // 名字颜色ARGB值
unsigned int nSupLevel; // 超玩等级
unsigned int nSoldierSoulAppear; // 兵魂外观
WORD nWeaponId; // 正在装备的武器id
unsigned int nGuildID; // 行会id
unsigned int nMonsterID; // 怪物模型id
unsigned int nMeritoriousPoint; // 累计功勋
unsigned int nNextSkillFlag; // 战士下一次技能标记
unsigned int nEvilPkStatus; // 恶意PK状态
unsigned int nPkValue; // PK值
// 下面还有Buff数据、效果数据。暂时没用到先不处理
}OtherActorPropData;
// 怪物数据
typedef struct tagMonsterPropData
{
EntityHandle handle; // 实体句柄
char szDecorateName[256]; // 修饰名称
WORD wPosX; // 实体坐标X
WORD wPosY; // 实体坐标Y
int nModelId; // 实体模型Id
BYTE ucDir; // 朝向
WORD ucLevel; // 等级
unsigned int nHP; // HP
unsigned int nMP; // MP
unsigned int nMaxHP; // MaxHP
unsigned int nMaxMP; // MaxMP
WORD wMoveSpeed; // 移动速度
WORD wAttkSpeed; // 攻击速度
unsigned int nStatus; // 状态掩码
unsigned int nNameColor; // 名字颜色ARGB值
WORD wMonsterId; // 怪物id
unsigned int nLiveTimeOut; // 生命到期时间
}MonsterPropData;
// 宠物数据
typedef struct tagPetPropData
{
EntityHandle handle; // 实体句柄
char szDecorateName[256]; // 修饰名称
WORD wPosX; // 实体坐标X
WORD wPosY; // 实体坐标Y
int nModelId; // 实体模型Id
BYTE ucDir; // 朝向
WORD ucLevel; // 等级
unsigned int nHP; // HP
unsigned int nMP; // MP
unsigned int nMaxHP; // MaxHP
unsigned int nMaxMP; // MaxMP
WORD wMoveSpeed; // 移动速度
WORD wAttkSpeed; // 攻击速度
unsigned int nStatus; // 状态掩码
unsigned int nNameColor; // 名字颜色ARGB值
WORD wEntityId; // 宠物id
}PetPropData;
typedef struct tagClientSkillData
{
WORD wSkillId;
BYTE ucSkillLevel;
WORD wSkillMiji;
int nSkillCD; // 技能CD
int nSkillExp; // 技能经验?
unsigned int nMijiExpireTick; // 秘籍过期时刻
BYTE nSkillInvalid; // 技能失效。1表示失效1表示正常
}ClientSkillData;
#pragma pack(pop)

View File

@@ -0,0 +1,94 @@
#include "stdafx.h"
const CSkillSystem::SkillMessageHandler CSkillSystem::s_aHandler[] = {
&CSkillSystem::DummySkillMsgHandler,
&CSkillSystem::ProcessRcvInitSkillList,
&CSkillSystem::LearnSkillResult
};
void CSkillSystem::OnRecvData(INT_PTR nCmd, CDataPacketReader& pack)
{
if (nCmd < 0 || nCmd >= ArrayCount(s_aHandler))
return;
(this->*s_aHandler[nCmd])(pack);
}
void CSkillSystem::OnTimeRun(TICKCOUNT currTick)
{
}
void CSkillSystem::ProcessRcvInitSkillList(CDataPacketReader& packet)
{
BYTE ucSkillCount = 0;
packet >> ucSkillCount;
if (ucSkillCount > 0)
{
ClientSkillData data;
packet >> data;
m_SkillList.add(data);
//OutputMsg(rmNormal, _T("[Skill] Recv Skill id=%d level=%d"), (int)data.wSkillId, (int)data.ucSkillLevel);
}
//OutputMsg(rmNormal, _T("[Skill] Recv Skill List, total skill count=%d"), (int)ucSkillCount);
}
void CSkillSystem::OnEnterGame()
{
RequestSkillList();
}
void CSkillSystem::RequestSkillList()
{
CDataPacket& pack = m_pClient->AllocProtoPacket();
pack << (BYTE)enSkillSystemID << (BYTE)cGetSkill;
m_pClient->FlushProtoPacket(pack);
}
void CSkillSystem::LearnSkillResult(CDataPacketReader& packet)
{
RequestSkillList();
}
void CSkillSystem::UseSkill(int nSkillId, EntityHandle targetHandle, int nX, int nY, int nDir)
{
if (m_SkillList.count() <= 0 || targetHandle.IsNull())
return;
if (nSkillId <= 0)
{
// 取第一个技能?
CClientActor& ca = m_pClient->GetActorData();
int job = ca.GetProperty<int>(PROP_ACTOR_VOCATION);
if (job == enVocWarrior)
{
NearAttack(targetHandle);
return;
}
if (job == enVocMagician)
{
nSkillId = 9;
}
if (job == enVocWizard)
{
nSkillId = 17;
}
}
CDataPacket& pack = m_pClient->AllocProtoPacket();
pack << (BYTE)enSkillSystemID << (BYTE)cUseSkill << (WORD)nSkillId;
pack << targetHandle << (WORD)nX << (WORD)nY << (BYTE)nDir;
m_pClient->FlushProtoPacket(pack);
}
void CSkillSystem::NearAttack(EntityHandle targetHandle)
{
int x = m_pClient->GetActorData().GetProperty<int>(PROP_ENTITY_POSX);
int y = m_pClient->GetActorData().GetProperty<int>(PROP_ENTITY_POSY);
int tarX,tarY;
m_pClient->GetLogicAgent().GetDefaultSystem().GetEntityPos(targetHandle, tarX,tarY);
INT_PTR nDir = CUtility::GetDir(x,y,tarX,tarY);
CDataPacket& pack = m_pClient->AllocProtoPacket();
pack << (BYTE)enSkillSystemID << (BYTE)cNearAttack << targetHandle << (BYTE)nDir << (WORD)0;
m_pClient->FlushProtoPacket(pack);
}

View File

@@ -0,0 +1,37 @@
#pragma once
class CSkillSystem : public CEntitySystem<enSkillSystemID>
{
public:
void OnRecvData(INT_PTR nCmd, CDataPacketReader& pack);
void OnTimeRun(TICKCOUNT currTick);
void OnEnterGame();
/*
* Comments: 使用技能
* Param int nSkillId: 技能Id
* Param EntityHandle targetHandle: 目标句柄
* Param int nX: 目标位置或者是鼠标位置X
* Param int nY: 目标位置或者是鼠标位置Y
* Param int nDir: 施法者的朝向
* @Return void:
* @Remark:
*/
void UseSkill(int nSkillId, EntityHandle targetHandle, int nX, int nY, int nDir);
// 接口协议里头还需要特效id、动作id 不是跟着技能走的?
void NearAttack(EntityHandle targetHandle);
INT_PTR GetSkillCount(){return m_SkillList.count();}
protected:
// 请求技能列表
void RequestSkillList();
// 占位的技能消息处理
void DummySkillMsgHandler(CDataPacketReader&){}
// 接受初始技能列表
void ProcessRcvInitSkillList(CDataPacketReader& packet);
void LearnSkillResult(CDataPacketReader& packet);
typedef void (CSkillSystem::*SkillMessageHandler)(CDataPacketReader&);
private:
CBaseList<ClientSkillData> m_SkillList;
static const SkillMessageHandler s_aHandler[];
};