Files
mir_server/server/LogicServer/quest/QuestSystem.h

242 lines
7.9 KiB
C
Raw Normal View History

2025-01-09 17:45:40 +08:00
#pragma once
#include<bitset>
/******************************************
*
*
* zac
*******************************************/
//class CEntitySystem;
class CQuestData;
class CActor;
class CNpc;
struct NpcTeleport
{
int nTelNpcId; //传送npcid
int nAuto;//自动
int nQid;//
int nQstate;//
int nIsOpen;//
NpcTeleport()
{
memset(this, 0, sizeof(*this));
}
};
#define MAXACTORQUEST 30 //最多30个任务
#define QUESTMAIN 10000 //
class CQuestSystem:
public CEntitySubSystem<enQuestSystemID,CQuestSystem,CActor>
{
public:
enum QuestEvent{
enOnCompleteQuest = 1, //任务完成
};
virtual bool Initialize(void *data,SIZE_T size);
//继承父类接口,处理网络数据包
virtual void ProcessNetData(INT_PTR nCmd,CDataPacketReader &packet );
//存盘
//把角色的任务数据保存到数据库中
void Save(PACTORDBDATA pData);
//定时处理
virtual VOID OnTimeCheck(TICKCOUNT nTickCount);
//从数据库读出数据,有某些任务是固定时段做的,所以从数据库读出的时候,要判断下这时候还能不能做
//不能做的话不能加到任务列表中,并把该任务改成超时状态
VOID OnDbRetData(INT_PTR nCmd,INT_PTR nErrorCode, CDataPacketReader &reader);
// //增加一个任务到列表中,nQid为对应的任务号,添加成功返回TRUE否则FALSE
// //能否接一个任务取决于:
// // 1、正在进行的任务列表是否含有该任务(不可以重复接、2、所在的场景或者对话npc是否匹配、3是否满足激活条件 4是否完成了父任务 5是否达到周期任务的条件
// // 6子任务未完成不能再接此任务 7、已经完成过的任务是否可以再次接
// /*
// * 备注:
// * 参数 int nQid:任务的id
// * 参数 BOOL bFlag:如果TRUE表示符合条件后会给玩家添加一个任务如果bFlag是False表示只是判断是否可以接这个任务不会自动给玩家增加任务
// * int* nRepeatTime:计算日常任务在周期内还剩多少次
// * bool boGoldAccept:是否包含用元宝可接
// * @Return int:
// */
bool AddQuest(QuestInfoCfg* cfg);
// int AddQuestToList( int nQid, const QuestConfig* pConfig );
// //判断某个任务是否已经完成
// BOOL IsFinish(INT_PTR nQid);
// //判断是否主线任务并且是否完成
// bool IsMainQuestFinish(INT_PTR nQid);
// VOID SetFinish(int nQid,bool boFlag = true);
// // 正常完成一个任务nQid为任务id
// // 正确返回0否则返回错误码完成成功会把存盘并且从正在进行的任务列表删除。
// // 注意:正常完成的任务需要正确接收到奖励才算完成
// int FinishQuest(int nQid,const QuestConfig* pConfig, bool boSpeedFin = false);
// 检查是否正在做这个任务
bool HasQuest(int nQid);
// int CanGetAward();
// /*
// * 备注:改变任务目标值的函数
// * 参数 int nQid:任务id
// * 参数 int nTargetId:需求目标id
// * 参数 int nId:代表某个类型的id比如物品id
// * 参数 int nValue:值
// * Param boAutoFinish:是否需要判断任务是否自动完成。在任务数据第一次从DB加载的时候不需要判断任务自动完成后面的时间会判断
// 因为有可能这个时候物品数据还没加载,收取任务奖励后可能会导致背包满了而无法加入用户原有的物品
// * @Return int:
// */
// VOID SetQuestValue(int nQid,int nId,int nValue,bool boAutoFinish);
// /*
// * 备注:每次增加目标值,+nValue
// * 参数 int nQid:任务id
// * 参数 int nTargetId:需求目标id
// * 参数 int nId:代表某个类型的id比如物品id
// * @Return int: 错误码0是正确非0失败
// */
// VOID AddQuestValue(int nQid,int nId,int nValue);
// /*
// * 备注:得到某个任务的需求值
// * 参数 int nQid:
// * 参数 int nTargetId:
// * 参数 int nId:
// * 参数 int nValue:
// * @Return int:
// */
// int GetQuestValue(int nQid,int nId);
// //获得某个任务配置
// const QuestConfig* GetQuestCfg(int index);
// /*
// * 备注:当npc进入视野时要计算这个npc身上是否有可领取的任务、或者交接的任务,如果有,要发消息通知客户端
// * 参数 CNPC * pNpc:
// * @Return VOID:
// */
// VOID SendNpcQuestState(CNpc* pNpc);
// /*
// * Comments:
// * Param int nTargetType:对应的目标类型,应该只处理杀怪和物品两种情况
// * Param int nId:对应的怪物id或者物品id等等
// * Param int nCount:变化的数值,增加是整数,减少是负数
// * @Return VOID:
// */
VOID OnQuestEvent(INT_PTR nTargetType, INT_PTR nCount, INT_PTR nId = 0);
// inline INT_PTR GetQuestCount() {return m_QuestList.size();}
//进入游戏
virtual void OnEnterGame();
// //任务传送
// void QuestTelport(int nQuestId,int nTargetId=-1);
// //主线任务传送
// void MainQuestTelport(int nQuestId, LPCTSTR sSceneName, LPCTSTR sNpcName , int nState);
public:
//构造函数和虚函数
CQuestSystem();
virtual ~CQuestSystem();
/*
* Comments:
* Param INT_PTR nSubEvent: ID
* Param INT_PTR nParam1:1-1
* Param INT_PTR nParam2:2-1
* Param INT_PTR nParam3:3-1
* Param INT_PTR nParam4:4-1
* @Return void:
*/
// void TriggerEvent(INT_PTR nSubEvent,INT_PTR nParam1=-1,INT_PTR nParam2=-1,INT_PTR nParam3=-1,INT_PTR nParam4=-1);
// /*是否在任务NPC附近*/
// bool IsNearByQuestNpc( WORD nQuestId, int nType );
/// 发送正在进行的任务数据
void SendAllQuestData();
//设置完成任务
void SetfinishQuest(int nQid);
//判断当前任务是否完成
int GetfinishQuestState(int nQid);
//检测可接取的任务
void CheckCanAcceptQuest();
//处理完成任务是状态的的自动切换
void DealAutoChangeQuestState(int Type, int nQid, int nState, QuestInfoCfg* cfg = NULL);
//修改任务状态
void ChangeQuestItemState(int nQid, int nState, Uint64 npcHandle = 0);
//获取正在进行的任务数据
QuestItem* GetGoingQuestData(int nQid);
//检测当前任务是否完成
bool CheckComplete(QuestItem* item, int nLimit);
//修改任务状态
bool ChangeGoingQuestState(int nQid, int nState);
//修改任务状态
bool ChangeGoingQuestState(std::vector<ChangeQuestState>& nChangeList);
bool returnQuestData(QuestItem* item,CDataPacket& DataPacket);
//是否在已接循环任务中
bool HasInRingQuest(int nQid);
//删除任务
void RemoveGoingQuestData(int nQid);
//发送新加的任务
void SendAddNewQuest(QuestItem* item);
//返回修改状态后的任务信息
void returnClientQuestState(int nQid, int nCode);
//返回修改状态后的任务信息
void SendClientQuestState(int nQid);
//保存
void SaveData();
//任务传送
void QuestTeleport(int nQid, int nType, int nId);
// //完成一个任务
// VOID SendFinishQuest(int nQid);
// void SetTelNpcId(int nNpc) { nTelNpcId = nNpc;}
// int GetTelNpcId() { return nTelNpcId;}
void SendQuestTelResult(int nCode = 0);
void ClearAllQuest();
bool GMSetQuestState(int nQid, int nState);
//处理以完成任务
void DealAutoCompleteCfgValue(int nQid);
private:
/*
* Comments:
* Param CDataPacketReader & packet:
* @Return void:
*/
// void CommonSpeedFinish(CDataPacketReader & packet);
public:
std::vector<QuestItem> m_GoingQuestList; //正在进行的任务列表及其数据
std::vector<int> m_RingStartQId; //环形任务初始id 用于判断自动接取不能重复的任务
char m_FinishedQuest[QUESTBTYE]; //已完成的任务id
CTimer<30000> m_timer; //定期刷新可接受任务的时间器,1分钟刷一次,
bool isDataModify ;// 数据变化
NpcTeleport m_infos;
};