818 lines
20 KiB
C++
818 lines
20 KiB
C++
#include "StdAfx.h"
|
||
#include "QuestSystem.h"
|
||
#include "../base/Container.hpp"
|
||
|
||
void CQuestSystem::OnEnterGame()
|
||
{
|
||
CheckCanAcceptQuest();
|
||
}
|
||
CQuestSystem::CQuestSystem()
|
||
{
|
||
m_GoingQuestList.clear();
|
||
isDataModify = false;
|
||
memset(m_FinishedQuest, 0, sizeof(m_FinishedQuest));
|
||
}
|
||
|
||
CQuestSystem::~CQuestSystem()
|
||
{
|
||
m_GoingQuestList.clear();
|
||
}
|
||
|
||
bool CQuestSystem::Initialize(void *data,SIZE_T size)
|
||
{
|
||
PACTORDBDATA pActorData = (ACTORDBDATA *)data;
|
||
if(pActorData ==NULL || size != sizeof(ACTORDBDATA))
|
||
{
|
||
OutputMsg(rmError,_T("data len error len=%d ,correct len=%d"),size, sizeof(ACTORDBDATA));
|
||
return false;
|
||
}
|
||
//将db的数据拷贝过来
|
||
memcpy( m_FinishedQuest,pActorData->quest,sizeof(m_FinishedQuest));
|
||
|
||
|
||
return true;
|
||
}
|
||
|
||
VOID CQuestSystem::OnDbRetData(INT_PTR nCmd,INT_PTR nErrorCode, CDataPacketReader &inPacket)
|
||
{
|
||
OutputMsg(rmNormal,_T("CQuestSystem::OnDbRetData nCmd=%d"), nCmd);
|
||
if (m_pEntity == NULL) return;
|
||
if (nCmd == jxInterSrvComm::DbServerProto::dcSaveQuest)
|
||
{
|
||
//这个是保存数据时返回的结果
|
||
if (nErrorCode != jxInterSrvComm::DbServerProto::reSucc)
|
||
{
|
||
OutputMsg(rmTip,_T("save quest data,errorcode=%d,ActorId=%d"),nErrorCode,m_pEntity->GetId());
|
||
}
|
||
return;
|
||
}
|
||
else if(nCmd == jxInterSrvComm::DbServerProto::dcLoadQuest)
|
||
{
|
||
m_GoingQuestList.clear();
|
||
WORD nCount = 0;
|
||
inPacket >> nCount;
|
||
if(HasDbDataInit()) return ; //如果已经装载了任务的数据,就不装载了
|
||
for (int i = 0; i < nCount; i++)
|
||
{
|
||
QuestItem item;
|
||
inPacket.readBuf(&item, sizeof(item));
|
||
if(item.nStartId > 0)
|
||
m_RingStartQId.push_back(item.nStartId);
|
||
m_GoingQuestList.push_back(item);
|
||
}
|
||
OnDbInitData();
|
||
//第一次下发可接任务
|
||
}
|
||
}
|
||
|
||
VOID CQuestSystem::OnTimeCheck(TICKCOUNT nTickCount)
|
||
{
|
||
}
|
||
|
||
void CQuestSystem::ProcessNetData(INT_PTR nCmd,CDataPacketReader &packet )
|
||
{
|
||
if (m_pEntity == NULL)
|
||
{
|
||
return;
|
||
}
|
||
switch (nCmd)
|
||
{
|
||
case sQueryQuest:
|
||
SendAllQuestData();
|
||
break;
|
||
case cChangetQuestState:
|
||
{
|
||
int nQid = 0;
|
||
int nState = 0;
|
||
Uint64 npcHandle = 0;
|
||
packet >> nQid >> nState >> npcHandle;
|
||
ChangeQuestItemState(nQid, nState, npcHandle);
|
||
break;
|
||
}
|
||
case cQuestTel: //传送
|
||
{
|
||
int nQid = 0;
|
||
BYTE nType = 0;
|
||
BYTE nId = 0;
|
||
packet >>nQid >> nType >> nId;
|
||
QuestTeleport(nQid, nType, nId);
|
||
break;
|
||
}
|
||
default:
|
||
OutputMsg(rmTip, _T("%s:客户端请求[%d]的数据包没处理,请检查是否做了多余的请求"), __FUNCTION__, nCmd);
|
||
break;
|
||
}
|
||
}
|
||
|
||
void CQuestSystem::QuestTeleport(int nQid, int nType, int nId)
|
||
{
|
||
if( !m_pEntity ) return;
|
||
int nCode = 0;
|
||
int nNpcId = 0;
|
||
int nIsOpen = 0;
|
||
int nQstate = 0;
|
||
int nAuto = 0;
|
||
do
|
||
{
|
||
CActor* pActor = (CActor*)m_pEntity;
|
||
if(GetfinishQuestState(nQid)) {
|
||
nCode = 1;
|
||
break;
|
||
}
|
||
|
||
QuestItem* item = GetGoingQuestData(nQid);
|
||
if(!item) {
|
||
nCode = 5;
|
||
break;
|
||
}
|
||
|
||
QuestInfoCfg* cfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(item->nQid, item->nState);
|
||
if(!cfg) {
|
||
nCode = 3;
|
||
break;
|
||
}
|
||
|
||
if(!GetLogicServer()->CheckOpenServer(cfg->nOpenDayLimit) || !m_pEntity->CheckLevel(cfg->nLevelLimit, cfg->nCircle)) {
|
||
nCode = 4;
|
||
break;
|
||
}
|
||
TeleportInfo* tel = cfg->GetTelInfo(nType, nId);
|
||
if(!tel)
|
||
{
|
||
nCode = 10;
|
||
break;
|
||
}
|
||
QuestAward pCost;;
|
||
cfg->GetCostFsValue(item->nUseFsTimes, pCost);
|
||
if(pCost.nCount)
|
||
{
|
||
if(!pActor->CheckActorSource(pCost.nType, pCost.nId, pCost.nCount, tstUI))
|
||
{
|
||
nCode = 20;
|
||
break;
|
||
}
|
||
}
|
||
int nEffId = GetLogicServer()->GetDataProvider()->GetGlobalConfig().nBlinkEnterEffect;
|
||
if( pActor->FlyShoseToStaticScene(tel->nMapid, tel->nX, tel->nY, tel->nRange,0,enDefaultTelePort,nEffId))
|
||
{
|
||
if(pCost.nCount)
|
||
{
|
||
pActor->RemoveConsume(pCost.nType, pCost.nId, pCost.nCount, -1, -1, -1, 0,GameLog::Log_Quest);
|
||
}
|
||
}
|
||
if(nType == 3)
|
||
{
|
||
item->nUseFsTimes++;
|
||
returnClientQuestState(nQid, 0);
|
||
}
|
||
m_infos.nAuto = tel->nAuto;
|
||
m_infos.nIsOpen = tel->nIsOpen;
|
||
m_infos.nQstate = item->nState;
|
||
m_infos.nTelNpcId = tel->nTelNpcId;
|
||
m_infos.nQid = nQid;
|
||
if(tel->nTelNpcId) {
|
||
return;
|
||
}
|
||
// nAuto = tel->nAuto;
|
||
// nIsOpen = tel->nIsOpen;
|
||
// nQstate = item->nState;
|
||
}
|
||
while(false);
|
||
// SendQuestTelResult(nCode);
|
||
CActorPacket ap;
|
||
CDataPacket & data = m_pEntity->AllocPacket(ap);
|
||
data<<(BYTE)GetSystemID() << (BYTE)sQuestTel;
|
||
data<<(BYTE)nCode;
|
||
data<<(BYTE)m_infos.nIsOpen;
|
||
data<<(BYTE)m_infos.nAuto;
|
||
data<<(int)m_infos.nQid;
|
||
data<<(int)m_infos.nQstate;
|
||
data<<(int)m_infos.nTelNpcId;
|
||
ap.flush();
|
||
memset(&m_infos, 0,sizeof(m_infos));
|
||
}
|
||
|
||
void CQuestSystem::SendQuestTelResult(int nCode)
|
||
{
|
||
if( nCode != 0 || m_infos.nTelNpcId != 0 )
|
||
{
|
||
CActorPacket ap;
|
||
CDataPacket & data = m_pEntity->AllocPacket(ap);
|
||
data<<(BYTE)GetSystemID() << (BYTE)sQuestTel;
|
||
data<<(BYTE)nCode;
|
||
data<<(BYTE)m_infos.nIsOpen;
|
||
data<<(BYTE)m_infos.nAuto;
|
||
data<<(int)m_infos.nQid;
|
||
data<<(int)m_infos.nQstate;
|
||
data<<(int)m_infos.nTelNpcId;
|
||
ap.flush();
|
||
memset(&m_infos, 0,sizeof(m_infos));
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void CQuestSystem::SendAllQuestData()
|
||
{
|
||
if (m_pEntity == NULL) return;
|
||
CActorPacket AP;
|
||
CDataPacket& DataPacket = m_pEntity->AllocPacket(AP);
|
||
|
||
//需保证任务数据已经从数据库中载入
|
||
DataPacket << (BYTE)enQuestSystemID << (BYTE)sQueryQuest;
|
||
//遍历任务数据
|
||
size_t nQCountPos = DataPacket.getPosition();
|
||
|
||
DataPacket << (int)m_GoingQuestList.size();//任务的数量
|
||
int nCount = 0;
|
||
for (int i = 0; i < m_GoingQuestList.size(); i++)
|
||
{
|
||
QuestItem& item = m_GoingQuestList[i];
|
||
QuestInfoCfg* cfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(item.nQid, item.nState);
|
||
if(!cfg)
|
||
continue;
|
||
if(GetfinishQuestState(item.nQid))
|
||
continue;
|
||
if(returnQuestData(&item, DataPacket))
|
||
nCount++;
|
||
|
||
}
|
||
int * pInt = (int*)DataPacket.getPositionPtr(nQCountPos);
|
||
*pInt = nCount;
|
||
AP.flush();
|
||
}
|
||
|
||
|
||
bool CQuestSystem::HasQuest(int nQid)
|
||
{
|
||
for(int i = 0; i < m_GoingQuestList.size(); i++)
|
||
{
|
||
if(m_GoingQuestList[i].nQid == nQid)
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
|
||
bool CQuestSystem::HasInRingQuest(int nQid)
|
||
{
|
||
for(int i = 0; i < m_RingStartQId.size(); i++)
|
||
{
|
||
if(m_RingStartQId[i] == nQid)
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/*
|
||
此方法尽量不要在高频方法中调用,如要调用,务必尽可能屏筛选掉不必要的循环
|
||
对于杀怪任务事件,首先由怪物的归属者处理事件,然后队友再处理
|
||
还有处理师徒关系
|
||
*/
|
||
VOID CQuestSystem::OnQuestEvent(INT_PTR nTargetType, INT_PTR nCount, INT_PTR nId)
|
||
{
|
||
if (m_pEntity == NULL) return;
|
||
for( int i = 0; i < m_GoingQuestList.size(); i++)
|
||
{
|
||
QuestItem& item = m_GoingQuestList[i];
|
||
|
||
int nQuestType = item.nType / 100;
|
||
int nSubType = item.nType % 100;
|
||
|
||
if(nTargetType == nQuestType)
|
||
{
|
||
QuestInfoCfg* cfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(item.nQid, item.nState);
|
||
if(!cfg)
|
||
continue;
|
||
int nSceneId = ((CActor*)m_pEntity)->GetSceneID();
|
||
if(!cfg->checkIdMapidInLimitIds(nId, nSceneId))
|
||
{
|
||
continue;
|
||
}
|
||
if(!cfg->inGroup(nId))
|
||
continue;
|
||
//处理技能 或者其他牵扯到子类型的任务进度
|
||
if(nQuestType == CQuestData::qtEquip && (cfg->GeLimitSubType() != 0 && cfg->GeLimitSubType() <= nId )) {
|
||
|
||
} else {
|
||
if(cfg->GeLimitSubType() != 0 && cfg->GeLimitSubType() != nId) {
|
||
continue;
|
||
}
|
||
}
|
||
|
||
if(nSubType == 1) //
|
||
item.nValue += nCount;
|
||
else {
|
||
if (item.nValue < nCount)
|
||
item.nValue = nCount;
|
||
}
|
||
isDataModify = true;
|
||
if(cfg->nShowSchedule)
|
||
{
|
||
returnClientQuestState(item.nQid, 0);
|
||
}
|
||
if(item.nValue >= cfg->GetLimitValue())
|
||
{
|
||
DealAutoChangeQuestState(2, item.nQid, item.nState, cfg);
|
||
returnClientQuestState(item.nQid, 0);
|
||
}
|
||
}
|
||
}
|
||
|
||
//如果是杀怪,并且同队伍的成员也有这个任务,则两个人都增加值(杀指定怪、场景怪、等级怪)
|
||
|
||
if (nTargetType == CQuestData::qtLevel || nTargetType == CQuestData::qtcircle)
|
||
{//如果等级变化了,更新可接任务列表
|
||
CheckCanAcceptQuest();
|
||
}
|
||
}
|
||
|
||
|
||
void CQuestSystem::CheckCanAcceptQuest() {
|
||
if (m_pEntity == NULL) return;
|
||
int Job = m_pEntity->GetProperty<int>(PROP_ACTOR_VOCATION);
|
||
std::map<int, QuestInfoCfg*>& questlist = GetLogicServer()->GetDataProvider()->GetQuestConfig()->m_vMainRootQuestConfig;
|
||
if(questlist.size() > 0) {
|
||
|
||
std::map<int, QuestInfoCfg*>::iterator it = questlist.begin();
|
||
for(; it != questlist.end(); it++) {
|
||
|
||
QuestInfoCfg* cfg = it->second;
|
||
int nJob = cfg->nQid /QUESTMAIN;
|
||
if( (nJob != 0 && nJob != Job) || HasQuest(cfg->nQid) || GetfinishQuestState(cfg->nQid) || HasInRingQuest(cfg->nQid))
|
||
continue;
|
||
if( (cfg->nFrontQid != 0 && !GetfinishQuestState(cfg->nFrontQid)))
|
||
continue;
|
||
|
||
// 等级检查
|
||
CActor* pActor = (CActor *)m_pEntity;
|
||
int level = pActor->GetLevel();
|
||
int circle = pActor->GetCircleLevel();
|
||
if (cfg->nQid == 1 && cfg->nState == 101 && circle >= 2)
|
||
{
|
||
continue;
|
||
}
|
||
if(GetLogicServer()->CheckOpenServer(cfg->nOpenDayLimit) && m_pEntity->CheckLevel(cfg->nLevelLimit, cfg->nCircle))
|
||
{
|
||
AddQuest(cfg);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|
||
|
||
|
||
int CQuestSystem::GetfinishQuestState(int nQid)
|
||
{
|
||
int nState = 0;
|
||
nQid = nQid%QUESTMAIN;
|
||
int nIndex = nQid/8;
|
||
int nbit = nQid%8 -1;
|
||
if(nbit < 0)
|
||
nbit = 7;
|
||
if((nIndex >= 0) || (nIndex < QUESTBTYE))
|
||
{
|
||
|
||
BYTE nValue = m_FinishedQuest[nIndex];
|
||
nState = (int)( nValue & (1 << nbit));
|
||
}
|
||
|
||
return nState;
|
||
}
|
||
|
||
void CQuestSystem::SetfinishQuest(int nQid)
|
||
{
|
||
nQid = nQid%QUESTMAIN;
|
||
int nIndex = nQid/8;
|
||
int nbit = nQid%8 -1;
|
||
if(nbit < 0)
|
||
nbit = 7;
|
||
if((nIndex >= 0) || (nIndex < QUESTBTYE))
|
||
{
|
||
BYTE nValue = m_FinishedQuest[nIndex];
|
||
nValue |= (1 << nbit);
|
||
m_FinishedQuest[nIndex] = (BYTE)nValue;
|
||
}
|
||
|
||
}
|
||
|
||
void CQuestSystem::ChangeQuestItemState(int nQid, int nState, Uint64 npcHandle)
|
||
{
|
||
if(!m_pEntity) return;
|
||
int nCode = 0;
|
||
do
|
||
{
|
||
if(GetfinishQuestState(nQid)) {
|
||
nCode = 1;
|
||
break;
|
||
}
|
||
|
||
if(!HasQuest(nQid)) {
|
||
nCode = 2;
|
||
break;
|
||
}
|
||
QuestItem* item = GetGoingQuestData(nQid);
|
||
if(!item || item->nState != nState) {
|
||
nCode = 5;
|
||
break;
|
||
}
|
||
|
||
QuestInfoCfg* cfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(nQid, nState);
|
||
if(!cfg) {
|
||
nCode = 3;
|
||
break;
|
||
}
|
||
|
||
if(!GetLogicServer()->CheckOpenServer(cfg->nOpenDayLimit) || !m_pEntity->CheckLevel(cfg->nLevelLimit, cfg->nCircle)) {
|
||
nCode = 4;
|
||
break;
|
||
}
|
||
//策划 王自宜 不需要判断npc 距离
|
||
// TeleportInfo* tel = cfg->GetTelInfo(1);
|
||
// if(tel && tel->nNpcId > 0)
|
||
// {
|
||
// CEntity* pEntity = GetGlobalLogicEngine()->GetEntityMgr()->GetEntity(npcHandle);
|
||
// if (!pEntity || !((CActor*)m_pEntity)->CheckTargetDistance((CActor*)pEntity, 15))
|
||
// {
|
||
// nCode = 14;
|
||
// break ;
|
||
// }
|
||
// }
|
||
|
||
if(!CheckComplete(item, cfg->mQuestInfo.nValue)) {
|
||
nCode = 6;
|
||
break;
|
||
}
|
||
|
||
DealAutoChangeQuestState(1, nQid, nState, cfg);
|
||
|
||
}while(false);
|
||
// //客户端需求 需要改变任务状态进行推送
|
||
// SendClientQuestState(nQid);
|
||
returnClientQuestState(nQid, nCode);
|
||
}
|
||
|
||
void CQuestSystem::returnClientQuestState(int nQid, int nCode)
|
||
{
|
||
QuestItem* item = GetGoingQuestData(nQid);
|
||
if(item)
|
||
{
|
||
CActorPacket ap;
|
||
CDataPacket &data = ((CActor*)m_pEntity)->AllocPacket(ap);
|
||
data <<(BYTE)enQuestSystemID <<(BYTE)sChangetQuestState;
|
||
data <<(BYTE)nCode;
|
||
returnQuestData(item, data);
|
||
ap.flush();
|
||
}
|
||
}
|
||
|
||
void CQuestSystem::SendClientQuestState(int nQid)
|
||
{
|
||
QuestItem* item = GetGoingQuestData(nQid);
|
||
if(item)
|
||
{
|
||
CActorPacket ap;
|
||
CDataPacket &data = ((CActor*)m_pEntity)->AllocPacket(ap);
|
||
data <<(BYTE)enQuestSystemID <<(BYTE)sChangeQuestState;
|
||
returnQuestData(item, data);
|
||
ap.flush();
|
||
}
|
||
}
|
||
|
||
|
||
void CQuestSystem::DealAutoChangeQuestState(int Type, int nQid, int nState, QuestInfoCfg* cfg)
|
||
{
|
||
if(!cfg) return;
|
||
|
||
if(cfg->awards.size() > 0)
|
||
{
|
||
if(!m_pEntity->GetBagSystem().bagIsEnough(BagRequest))
|
||
{
|
||
m_pEntity->SendTipmsgFormatWithId(tmLeftBagNumNotEnough,tstUI);
|
||
return;
|
||
}
|
||
|
||
for(int k = 0; k < cfg->awards.size(); k++)
|
||
{
|
||
((CActor*)m_pEntity)->GiveAward(cfg->awards[k].nType, cfg->awards[k].nId,cfg->awards[k].nCount,0,0,0,0, GameLog::Log_Quest);
|
||
}
|
||
}
|
||
int Job = m_pEntity->GetProperty<int>(PROP_ACTOR_VOCATION);
|
||
std::vector<ChangeQuestState> Lists;
|
||
Lists.clear();
|
||
if(Type == 1)
|
||
Lists = cfg->button;
|
||
else
|
||
Lists = cfg->nAuto;
|
||
|
||
if(Lists.size() > 0) {
|
||
|
||
for(int i = 0; i < Lists.size(); i++) {
|
||
|
||
if(!ChangeGoingQuestState(Lists[i].nQid, Lists[i].nState)) {
|
||
|
||
QuestInfoCfg* newCfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(Lists[i].nQid, Lists[i].nState);
|
||
if(!newCfg)
|
||
continue;
|
||
int nJob = newCfg->nQid /QUESTMAIN;
|
||
if( nJob != 0 && nJob != Job)
|
||
continue;
|
||
if(GetLogicServer()->CheckOpenServer(newCfg->nOpenDayLimit) && m_pEntity->CheckLevel(newCfg->nLevelLimit, newCfg->nCircle)) {
|
||
AddQuest(newCfg);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
if(cfg->nIscomplete) {
|
||
|
||
if(cfg->nAnnular == 0)
|
||
SetfinishQuest(nQid);
|
||
|
||
//记录状态
|
||
GetLogicServer()->SendTaskLocalLog(nQid, ((CActor*)m_pEntity), cfg->ntasktype, 2);
|
||
RemoveGoingQuestData(nQid);
|
||
CActorPacket ap;
|
||
CDataPacket &data = ((CActor*)m_pEntity)->AllocPacket(ap);
|
||
data <<(BYTE)enQuestSystemID <<(BYTE)sDeleteQuest;
|
||
data <<(int)nQid;
|
||
data <<(int)nState;
|
||
ap.flush();
|
||
CScriptValueList paramList,retList;
|
||
static CNpc* globalNpc = GetGlobalLogicEngine()->GetGlobalNpc();
|
||
paramList << (int)enOnCompleteQuest;
|
||
paramList << (int)nQid;
|
||
paramList << m_pEntity;
|
||
if(!globalNpc->GetScript().CallModule("QuestDispatcher","OnEvent", paramList, retList, 1))
|
||
{
|
||
OutputMsg(rmError,"[QuestSystem] OnEvent CheckEnter 错误,任务ID=%d!",nQid);
|
||
}
|
||
// if(retList.count() >= 0 && (bool)retList[0] == false)
|
||
// {
|
||
// return;
|
||
// }
|
||
}
|
||
|
||
}
|
||
|
||
|
||
QuestItem* CQuestSystem::GetGoingQuestData(int nQid)
|
||
{
|
||
for(int i = 0; i < m_GoingQuestList.size(); i++)
|
||
{
|
||
if(m_GoingQuestList[i].nQid == nQid)
|
||
return &m_GoingQuestList[i];
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
void CQuestSystem::RemoveGoingQuestData(int nQid)
|
||
{
|
||
std::vector<QuestItem>::iterator it = m_GoingQuestList.begin();
|
||
for(; it != m_GoingQuestList.end();)
|
||
{
|
||
if((*it).nQid == nQid)
|
||
{
|
||
it =m_GoingQuestList.erase(it);
|
||
}
|
||
else
|
||
{
|
||
it++;
|
||
}
|
||
}
|
||
isDataModify = true;
|
||
}
|
||
|
||
|
||
bool CQuestSystem::ChangeGoingQuestState(int nQid, int nState)
|
||
{
|
||
QuestItem* item = GetGoingQuestData(nQid);
|
||
if(item)
|
||
{
|
||
QuestInfoCfg* cfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(nQid, nState);
|
||
if(!cfg) {
|
||
return false;
|
||
}
|
||
item->nState = nState;
|
||
item->nType = cfg->GeLimitType();
|
||
//客户端需求 需要改变任务状态进行推送
|
||
SendClientQuestState(nQid);
|
||
if (cfg->nAcceptState)
|
||
GetLogicServer()->SendTaskLocalLog(nQid, ((CActor*)m_pEntity), cfg->ntasktype, 1);
|
||
DealAutoCompleteCfgValue(nQid);
|
||
isDataModify = true;
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
bool CQuestSystem::returnQuestData(QuestItem* item, CDataPacket& DataPacket)
|
||
{
|
||
if(item )
|
||
{
|
||
QuestInfoCfg* cfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(item->nQid, item->nState);
|
||
if(!cfg) {
|
||
return false;
|
||
}
|
||
DataPacket << item->nQid;
|
||
DataPacket << item->nState;
|
||
DataPacket << cfg->GetLimitValue();
|
||
DataPacket << item->nValue;
|
||
QuestAward pCost;
|
||
cfg->GetCostFsValue(item->nUseFsTimes, pCost);
|
||
// QuestCostFlyshoe* pCost = cfg->GetCostFsValue(item->nUseFsTimes);
|
||
DataPacket <<(int)(pCost.nCount);
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
//重载
|
||
bool CQuestSystem::ChangeGoingQuestState(std::vector<ChangeQuestState>& nChangeList)
|
||
{
|
||
if(nChangeList.size() > 0)
|
||
{
|
||
for(int i = 0; i < nChangeList.size(); i++)
|
||
{
|
||
ChangeGoingQuestState(nChangeList[i].nQid, nChangeList[i].nState);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
bool CQuestSystem::CheckComplete(QuestItem* item, int nLimit)
|
||
{
|
||
if(nLimit == 0) return true;
|
||
if(!item) return false;
|
||
|
||
if(item->nValue >= nLimit)
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
bool CQuestSystem::AddQuest(QuestInfoCfg* cfg)
|
||
{
|
||
if(!cfg) return false;
|
||
QuestItem item;
|
||
item.nQid = cfg->nQid;
|
||
item.nType = cfg->mQuestInfo.nType;
|
||
item.nState = cfg->nState;
|
||
if (cfg->nAcceptState)
|
||
GetLogicServer()->SendTaskLocalLog(cfg->nQid, ((CActor*)m_pEntity), cfg->ntasktype, 1);
|
||
//记录接取状态
|
||
// GetLogicServer()->SendTaskLocalLog(cfg->nQid, ((CActor*)m_pEntity), cfg->mQuestInfo.nType, cfg->nState);
|
||
if(CheckComplete(&item, cfg->mQuestInfo.nValue))
|
||
{
|
||
ChangeGoingQuestState(cfg->nAuto);
|
||
}
|
||
|
||
if(cfg->nAnnular)
|
||
{
|
||
item.nStartId = cfg->nAnnular;
|
||
m_RingStartQId.push_back(item.nStartId);
|
||
}
|
||
m_GoingQuestList.push_back(item);
|
||
|
||
if (!((CActor*)m_pEntity)->OnGetIsTestSimulator()
|
||
&& !((CActor*)m_pEntity)->OnGetIsSimulator())
|
||
{
|
||
SendAddNewQuest(&item);
|
||
}
|
||
DealAutoCompleteCfgValue(cfg->nQid);
|
||
isDataModify = true;
|
||
return true;
|
||
}
|
||
|
||
void CQuestSystem::SendAddNewQuest(QuestItem* item)
|
||
{
|
||
CActorPacket ap;
|
||
CDataPacket &data = ((CActor*)m_pEntity)->AllocPacket(ap);
|
||
data <<(BYTE)enQuestSystemID <<(BYTE)sAddQuest;
|
||
returnQuestData(item, data);
|
||
ap.flush();
|
||
}
|
||
void CQuestSystem::Save(PACTORDBDATA pActorData)
|
||
{
|
||
|
||
memcpy(pActorData->quest, m_FinishedQuest,sizeof(m_FinishedQuest));
|
||
SaveData();
|
||
}
|
||
|
||
//保存玩家成就完成进度情况
|
||
void CQuestSystem::SaveData()
|
||
{
|
||
if(!m_pEntity) return;
|
||
|
||
// if(!isInitData) return;
|
||
|
||
if(!isDataModify) return;
|
||
|
||
CDataPacket& dataPacket = GetLogicServer()->GetDbClient()->allocProtoPacket(jxInterSrvComm::DbServerProto::dcSaveQuest);
|
||
dataPacket <<((CActor*)m_pEntity)->GetRawServerIndex() << GetLogicServer()->GetServerIndex();
|
||
|
||
dataPacket <<(unsigned int)m_pEntity->GetId(); //玩家id
|
||
size_t count = m_GoingQuestList.size();
|
||
dataPacket <<(int)count;
|
||
for(int i = 0; i < count; i++)
|
||
{
|
||
QuestItem & item = m_GoingQuestList[i];
|
||
dataPacket.writeBuf(&item, sizeof(item));
|
||
}
|
||
GetLogicServer()->GetDbClient()->flushProtoPacket(dataPacket);
|
||
|
||
isDataModify = false;
|
||
}
|
||
|
||
|
||
|
||
void CQuestSystem::ClearAllQuest()
|
||
{
|
||
m_GoingQuestList.clear();
|
||
memset(m_FinishedQuest, 0 ,sizeof(m_FinishedQuest));
|
||
m_RingStartQId.clear();
|
||
CheckCanAcceptQuest();
|
||
}
|
||
|
||
|
||
bool CQuestSystem::GMSetQuestState(int nQid, int nState)
|
||
{
|
||
if(!ChangeGoingQuestState(nQid, nState)) {
|
||
|
||
QuestInfoCfg* newCfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(nQid, nState);
|
||
if(newCfg) {
|
||
AddQuest(newCfg);
|
||
}
|
||
}
|
||
|
||
QuestItem* item = GetGoingQuestData(nQid);
|
||
if(item)
|
||
{
|
||
QuestInfoCfg* newCfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(nQid, nState);
|
||
if(newCfg && item->nValue < newCfg->GetLimitValue())
|
||
item->nValue = 0;
|
||
returnClientQuestState(nQid, 0);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
//对于等级 装备等 需要自动判定是否已经完成了任务
|
||
void CQuestSystem::DealAutoCompleteCfgValue(int nQid)
|
||
{
|
||
QuestItem* item = GetGoingQuestData(nQid);
|
||
if(item)
|
||
{
|
||
QuestInfoCfg* cfg = GetLogicServer()->GetDataProvider()->GetQuestConfig()->GetQuestConfig(nQid, item->nState);
|
||
if(!cfg) {
|
||
return;
|
||
}
|
||
int nQuestType = cfg->GeLimitType() / 100;
|
||
bool nFalg = false;
|
||
if(nQuestType== CQuestData::qtEquip)
|
||
{
|
||
m_pEntity->GetEquipmentSystem().DealEquipmentAchieve();
|
||
}
|
||
else if(nQuestType == CQuestData::qtLevel)
|
||
{
|
||
|
||
OnQuestEvent(CQuestData::qtLevel, ((CActor*)m_pEntity)->GetLevel());
|
||
}
|
||
else if(nQuestType == CQuestData::qtcircle)
|
||
{
|
||
if(cfg->GetLimitValue() <= ((CActor*)m_pEntity)->GetCircleLevel() )
|
||
{
|
||
OnQuestEvent(CQuestData::qtcircle, ((CActor*)m_pEntity)->GetCircleLevel());
|
||
}
|
||
}
|
||
else if(nQuestType == CQuestData::qtSkillLv)
|
||
{
|
||
int nSkillLv = m_pEntity->GetSkillSystem().GetSkillLevel(cfg->GeLimitSubType());
|
||
if(cfg->GetLimitValue() <= nSkillLv )
|
||
{
|
||
OnQuestEvent(CQuestData::qtSkillLv, nSkillLv, cfg->GeLimitSubType());
|
||
}
|
||
}
|
||
else if(nQuestType == CQuestData::qtBless)
|
||
{
|
||
int nBlessValue = ((CActor*)m_pEntity)->GetProperty<unsigned int>(PROP_ACTOR_Bless);
|
||
int nBlessLv = 0;
|
||
BlessCfg* pBlessCfg = GetLogicServer()->GetDataProvider()->GetBlessCfg().GetBlessCfg(nBlessValue);
|
||
if(pBlessCfg)
|
||
{
|
||
nBlessLv = pBlessCfg->nLevel;
|
||
}
|
||
|
||
OnQuestEvent(CQuestData::qtBless, nBlessLv, cfg->GeLimitSubType());
|
||
}
|
||
}
|
||
}
|