Files
2026-06-01 12:46:52 +02:00

231 lines
9.5 KiB
C++

#pragma once
#include "QuestInstance.h"
//#include <vector>
#include <map>
#include <mmo/ArType.h>
class SGame;
class cQuestMarkFactory;
class SQuestMgr
{
private:
/// 퀘스트의 체크 상태들(check, new, new elapsed time)
struct sQuestCheckStatus
{
sQuestCheckStatus() : isCheck(false), isNew(false), elapsedNewTime(0.0f) {}
bool isCheck; /// 2011.09.27 체크 상태 - prodongi
bool isNew;
float elapsedNewTime;
};
struct _QUEST
{
_QUEST( QuestBase::QuestCode _code, int nStatus[ QuestInstance::MAX_STATUS ], int _nRandomValue[ QuestInstance::MAX_RANDOM_VALUE ], int start_id, AR_TIME timeLimit, unsigned char progress, bool pending=false )
: code( _code ) , nStartID( start_id ), nTimeLimit(timeLimit), nProgress(progress), bPending(pending)
{
memcpy( status, nStatus, sizeof(status) );
memcpy( nRandomValue, _nRandomValue, sizeof(nRandomValue) );
isNotice = false;
checkStatus.isCheck = false;
checkStatus.isNew = false;
}
_QUEST(_QUEST const& quest)
{
*this = quest;
}
void operator = (_QUEST const& quest)
{
code = quest.code;
nStartID = quest.nStartID;
memcpy( status, quest.status, sizeof(status) );
memcpy( nRandomValue, quest.nRandomValue, sizeof(nRandomValue) );
nTimeLimit = quest.nTimeLimit;
isNotice = quest.isNotice;
nProgress = quest.nProgress;
bPending = quest.bPending;
checkStatus.isCheck = quest.checkStatus.isCheck;
checkStatus.isNew = quest.checkStatus.isNew;
checkStatus.elapsedNewTime = quest.checkStatus.elapsedNewTime;
}
void swap(_QUEST& quest)
{
_QUEST old(quest);
quest = *this;
*this = old;
}
bool updateNew(float elapsedtime)
{
if (!checkStatus.isNew)
return false;
checkStatus.elapsedNewTime += elapsedtime;
if (checkStatus.elapsedNewTime >= MAX_NEW_SHOW_TIME)
{
setIsNew(false);
return true;
}
return false;
}
void setIsNew(bool is)
{
checkStatus.isNew = is;
if (checkStatus.isNew)
checkStatus.elapsedNewTime = 0.0f;
}
QuestBase::QuestCode code;
int nStartID;
int status[ QuestInstance::MAX_STATUS ];
int nRandomValue[ QuestInstance::MAX_RANDOM_VALUE ];
AR_TIME nTimeLimit;
bool isNotice; ///< 남은 시간이 제한시간 반이면 공지 한번 해주기
unsigned char nProgress;
bool bPending; ///< 대기상태인가? 2009.11.23 sfreer
sQuestCheckStatus checkStatus; /// 2011.09.27 체크 상태 - prodongi
static float MAX_NEW_SHOW_TIME;
};
typedef std::vector< _QUEST > v_quest;
public:
virtual ~SQuestMgr();
enum QUEST_PROGRESS
{
STARTABLE = 0,
IN_PROGRESS = 1,
FINISHABLE = 2,
QUEST_IN_PROGRESS = 1, ///< 퀘스트 진행중
QUEST_SUCCEED = 2, ///< 퀘스트 성공
QUEST_FAILED = 100, ///< 퀘스트 실패
};
enum { MAX_QUEST_NUM = 20 }; /// 2011.09.29 최대 받을 수 있는 퀘스트 개수 - prodongi
bool IsAddQuest( QuestBase::QuestCode code );
void InsertQuest( QuestBase::QuestCode code, int nStatus[ QuestInstance::MAX_STATUS ], int nRandomValue[ QuestInstance::MAX_RANDOM_VALUE ],int nStartID, AR_TIME nTimeLimit, unsigned char nProgress, bool bPending = false);
void ChangeStatus( QuestBase::QuestCode code, int nStatus[ QuestInstance::MAX_STATUS ], unsigned char nProgress );
void FinishQuest( QuestBase::QuestCode code );
void RemoveQuest( QuestBase::QuestCode code );
size_t GetQuestCount(unsigned int type = 0);
int GetQuestStatus( QuestBase::QuestCode code, size_t status_idx );
int GetQuestRandomValue( QuestBase::QuestCode code, size_t idx );
QuestBase::QuestCode GetQuestCodeByIndex( size_t idx, unsigned int type = 0 );
bool getQuestCheckByIndex(size_t idx, unsigned int type = 0); /// 2011.09.27 - prodongi
void setQuestCheckByIndex(size_t idx, bool isCheck, unsigned int type = 0);
/// 2011.09.28 퀘스트가 new 인지를 리턴 - prodongi
bool getQuestIsNewByIndex(size_t idx, unsigned int type = 0);
/// 2011.11.03 퀘스트 코드를 가지고 퀘스트 리스트 인덱스를 구한다 - prodongi
int getQuestIndexByCode(QuestBase::QuestCode code, unsigned int type = 0);
/// 2011.10.06 성공 여부 리스트를 구한다 - prodongi
void getSuccessList(std::vector<bool>& successList, QuestBase::QuestCode code);
int GetQuestStartID( QuestBase::QuestCode code );
AR_TIME GetQuestTimeLimit( QuestBase::QuestCode code );
QuestBase::QuestCode GetCurrentQuest() const { return m_nCurrentQuest; }
void SetCurrentQuest( QuestBase::QuestCode code ) { m_nCurrentQuest = code; }
bool IsPendingQuest( QuestBase::QuestCode code );
unsigned char GetQuestProgress( QuestBase::QuestCode code );
void SetQuestProgress( QuestBase::QuestCode code, unsigned char nProgress, unsigned int type = 0 );
static SQuestMgr & GetInstance();
void Clear();
void Process(unsigned long time);
void SetGame( SGame* pGame ) { m_pGame = pGame; }
/// 2011.08.05 - prodongi
bool isQuestMarkMob(int enc_id_value, bool checkQuestInProgress = false);
bool isQuestMarkDropItem(int dropItemId, bool checkQuestInProgress = false);
bool isQuestMarkNpc(int id, bool checkQuestInProgress = false);
bool isQuestMarkProp(int id, bool checkQuestInProgress = false);
void iterBeginQuestList(unsigned int type);
bool iterIsEndQuestList(unsigned int type);
void iterNextQuestList();
QuestBase::QuestCode iterDataQuestList();
void getMonsterList(QuestBase::QuestCode code, std::vector<int>& mobList);
/// 2011.10.05 퀘스트의 프랍 리스트를 구한다 - prodongi
void getItemList(QuestBase::QuestCode code, std::vector<int>& propList);
/// 2011.09.20 표식 속성 데이타를 갖고 온다 - prodongi
bool getMarkProp(QuestBase::QuestCode code, int& type, int& id, bool& hide);
/// 2011.09.27 sortList 순서대로 퀘스트 리스트를 정렬 한다
void sortByCheckStatus(bool isCheck, unsigned int type = 0);
/// 2011.09.28 관련 데이타들을 저장해 놓는다 - prodongi
void saveData();
/// 2011.09.28 저장한 데이타들을 복구한다- prodongi
void restoreData();
/// 2012.04.03 퀘스트 목록 중에서 id가 성공 상태인지 아닌지 체크, - prodongi
/// 같은 id 항목을 갖는 퀘스트가 여러개 있을 수 있기 때문에 모두 확인해 봐야 된다.
bool isNotSuccess(int id);
private:
v_quest& getQuestList(unsigned int type);
v_quest& getOriginalQuestList(unsigned int type);
bool IsAddQuest( QuestBase::QuestCode code, v_quest& questList );
void InsertQuest( QuestBase::QuestCode code, v_quest& questList, int nStatus[ QuestInstance::MAX_STATUS ], int nRandomValue[ QuestInstance::MAX_RANDOM_VALUE ],int nStartID, AR_TIME nTimeLimit, unsigned char nProgress, bool bPending = false);
void ChangeStatus( QuestBase::QuestCode code, v_quest& questList, int nStatus[ QuestInstance::MAX_STATUS ], unsigned char nProgress );
void RemoveQuest( QuestBase::QuestCode code, v_quest& questList );
QuestBase::QuestCode GetQuestCodeByIndex( size_t idx, v_quest const& questList ) const;
bool IsPendingQuest( QuestBase::QuestCode code, v_quest& questList ) const;
int GetQuestStartID( QuestBase::QuestCode code, v_quest& questList ) const;
AR_TIME GetQuestTimeLimit( QuestBase::QuestCode code, v_quest& questList ) const;
int GetQuestStatus( QuestBase::QuestCode code, size_t status_idx, v_quest& questList ) const;
int GetQuestRandomValue( QuestBase::QuestCode code, size_t idx, v_quest& questList ) const;
unsigned char GetQuestProgress( QuestBase::QuestCode code, v_quest& questList ) const;
void SetQuestProgress( QuestBase::QuestCode code, unsigned char nProgress, v_quest& questList );
/// 2011.09.28 퀘스트 리스트의 체크 상태를 저장한다, 퀘스트 리스트를 받은 후에 복구 하기 위해 저장함 - prodongi
void saveCheckStatus();
/// 2011.09.28 저장한 체크 상태를 복구 시킨다 - prodongi
void restoreCheckStatus();
void restoreCheckStatus(v_quest& questList);
/// 2011.09.28 새로 추가된 퀘스트를 찾아서 m_savedCheckStatus에 추가 해준다 - prodongi
void addSavedCheckStatusAtNew();
/// 2011.09.27 sortList 순서대로 퀘스트 리스트를 정렬 한다
void sortByCheckStatus(v_quest& questList);
/// 2011.10.06 new 상태를 맨 처음으로 정렬 시킨다. - prodongi
void sortByNewStatus(v_quest &questList);
bool getQuestCheckByIndex(size_t idx, v_quest& questList); /// 2011.09.27 - prodongi
void setQuestCheckByIndex(size_t idx, bool isCheck, v_quest& questList);
void setQuestCheckByIndex(QuestBase::QuestCode code, bool isCheck, v_quest& questList);
bool getQuestIsNewByIndex(size_t idx, v_quest& questList);
void Process(float elapsedtime, v_quest& questList);
_QUEST const* getQuest(QuestBase::QuestCode code);
/// 2011.11.02 new 상태의 퀘스트를 맨 앞으로 오게 한다 - prodongi
void sortByNewStatus();
/// 2011.11.03 원래의 퀘스트 리스트 코드를 저장한다 - prodongi
void saveOriginalQuestList();
/// 2011.11.07 questList에 원본 퀘스트 리스트를 설정한다
void setQuestListAtOriginalQuest(v_quest& questList, unsigned int type);
private:
enum { TYPE_DEFAULT, TYPE_NUM };
SQuestMgr();
QuestBase::QuestCode m_nCurrentQuest;
/// 20111.11.07 체크 상태/new 에 따라서 정렬된 리스트 - prodongi
v_quest m_vQuestList[TYPE_NUM];
/// 2011.09.01 - prodongi
v_quest::iterator m_iterQuestList;
cQuestMarkFactory* m_markFactory;
/// 2011.09.28 저장된 퀘스트 리스트의 체크 상태 - prodongi
std::map<QuestBase::QuestCode, sQuestCheckStatus> m_savedCheckStatus;
unsigned long m_time;
/// 20111.11.07 서버에서 받은 원본 리스트 - prodongi
v_quest m_originalQuestList[TYPE_NUM];
class SGame * m_pGame;
};