forked from metin2/server
264 lines
8.0 KiB
C++
264 lines
8.0 KiB
C++
#ifndef __METIN2_SERVER_QUEST_MANAGER__
|
|
#define __METIN2_SERVER_QUEST_MANAGER__
|
|
|
|
#include <unordered_map>
|
|
|
|
#include "questnpc.h"
|
|
|
|
class ITEM;
|
|
class CHARACTER;
|
|
class CDungeon;
|
|
|
|
namespace quest
|
|
{
|
|
using namespace std;
|
|
|
|
bool IsScriptTrue(const char* code, int size);
|
|
string ScriptToString(const string& str);
|
|
|
|
class CQuestManager : public singleton<CQuestManager>
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
QUEST_SKIN_NOWINDOW,
|
|
QUEST_SKIN_NORMAL,
|
|
//QUEST_SKIN_CINEMATIC,
|
|
QUEST_SKIN_SCROLL=4,
|
|
QUEST_SKIN_CINEMATIC=5,
|
|
QUEST_SKIN_COUNT
|
|
};
|
|
|
|
typedef map<string, int> TEventNameMap;
|
|
typedef map<unsigned int, PC> PCMap;
|
|
|
|
public:
|
|
CQuestManager();
|
|
virtual ~CQuestManager();
|
|
|
|
bool Initialize();
|
|
void Destroy();
|
|
|
|
bool InitializeLua();
|
|
lua_State * GetLuaState() { return L; }
|
|
void AddLuaFunctionTable(const char * c_pszName, luaL_reg * preg);
|
|
|
|
TEventNameMap m_mapEventName;
|
|
|
|
QuestState OpenState(const string& quest_name, int state_index);
|
|
void CloseState(QuestState& qs);
|
|
bool RunState(QuestState& qs);
|
|
|
|
PC * GetPC(unsigned int pc);
|
|
PC * GetPCForce(unsigned int pc); // 현재 PC를 바꾸지 않고 PC 포인터를 가져온다.
|
|
|
|
unsigned int GetCurrentNPCRace();
|
|
const string & GetCurrentQuestName();
|
|
unsigned int FindNPCIDByName(const string& name);
|
|
|
|
//void SetCurrentNPCCharacterPtr(LPCHARACTER ch) { m_pkCurrentNPC = ch; }
|
|
LPCHARACTER GetCurrentNPCCharacterPtr();
|
|
|
|
void SetCurrentEventIndex(int index) { m_iRunningEventIndex = index; }
|
|
|
|
bool UseItem(unsigned int pc, LPITEM item, bool bReceiveAll);
|
|
bool PickupItem(unsigned int pc, LPITEM item);
|
|
bool SIGUse(unsigned int pc, DWORD sig_vnum, LPITEM item, bool bReceiveAll);
|
|
bool TakeItem(unsigned int pc, unsigned int npc, LPITEM item);
|
|
LPITEM GetCurrentItem();
|
|
void ClearCurrentItem();
|
|
void SetCurrentItem(LPITEM item);
|
|
void AddServerTimer(const string& name, DWORD arg, LPEVENT event);
|
|
void ClearServerTimer(const string& name, DWORD arg);
|
|
void ClearServerTimerNotCancel(const string& name, DWORD arg);
|
|
void CancelServerTimers(DWORD arg);
|
|
|
|
void SetServerTimerArg(DWORD dwArg);
|
|
DWORD GetServerTimerArg();
|
|
|
|
// event over state and stae
|
|
bool ServerTimer(unsigned int npc, unsigned int arg);
|
|
|
|
void Login(unsigned int pc, const char * c_pszQuestName = NULL);
|
|
void Logout(unsigned int pc);
|
|
bool Timer(unsigned int pc, unsigned int npc);
|
|
bool Click(unsigned int pc, LPCHARACTER pkNPC);
|
|
void Kill(unsigned int pc, unsigned int npc);
|
|
void LevelUp(unsigned int pc);
|
|
void AttrIn(unsigned int pc, LPCHARACTER ch, int attr);
|
|
void AttrOut(unsigned int pc, LPCHARACTER ch, int attr);
|
|
bool Target(unsigned int pc, DWORD dwQuestIndex, const char * c_pszTargetName, const char * c_pszVerb);
|
|
bool GiveItemToPC(unsigned int pc, LPCHARACTER pkChr);
|
|
void Unmount(unsigned int pc);
|
|
|
|
void QuestButton(unsigned int pc, unsigned int quest_index);
|
|
void QuestInfo(unsigned int pc, unsigned int quest_index);
|
|
|
|
void EnterState(DWORD pc, DWORD quest_index, int state);
|
|
void LeaveState(DWORD pc, DWORD quest_index, int state);
|
|
|
|
void Letter(DWORD pc);
|
|
void Letter(DWORD pc, DWORD quest_index, int state);
|
|
|
|
void ItemInformer(unsigned int pc, unsigned int vnum); //독일선물기능
|
|
|
|
//
|
|
|
|
bool CheckQuestLoaded(PC* pc) { return pc && pc->IsLoaded(); }
|
|
|
|
// event occurs in one state
|
|
void Select(unsigned int pc, unsigned int selection);
|
|
void Resume(unsigned int pc);
|
|
void Input(unsigned int pc, const char* msg);
|
|
void Confirm(unsigned int pc, EQuestConfirmType confirm, unsigned int pc2 = 0);
|
|
void SelectItem(unsigned int pc, unsigned int selection);
|
|
|
|
void LogoutPC(LPCHARACTER ch);
|
|
void DisconnectPC(LPCHARACTER ch);
|
|
|
|
QuestState * GetCurrentState() { return m_CurrentRunningState; }
|
|
|
|
void LoadStartQuest(const string& quest_name, unsigned int idx);
|
|
//bool CanStartQuest(const string& quest_name, const PC& pc);
|
|
bool CanStartQuest(unsigned int quest_index, const PC& pc);
|
|
bool CanStartQuest(unsigned int quest_index);
|
|
bool CanEndQuestAtState(const string& quest_name, const string& state_name);
|
|
|
|
LPCHARACTER GetCurrentCharacterPtr() { return m_pCurrentCharacter; }
|
|
LPCHARACTER GetCurrentPartyMember() { return m_pCurrentPartyMember; }
|
|
PC * GetCurrentPC() { return m_pCurrentPC; }
|
|
|
|
LPDUNGEON GetCurrentDungeon();
|
|
void SelectDungeon(LPDUNGEON pDungeon);
|
|
|
|
void ClearScript();
|
|
void SendScript();
|
|
void AddScript(const string& str);
|
|
|
|
void BuildStateIndexToName(const char* questName);
|
|
|
|
int GetQuestStateIndex(const string& quest_name, const string& state_name);
|
|
const char* GetQuestStateName(const string& quest_name, const int state_index);
|
|
|
|
void SetSkinStyle(int iStyle);
|
|
|
|
void SetNoSend() { m_bNoSend = true; }
|
|
|
|
unsigned int LoadTimerScript(const string& name);
|
|
|
|
//unsigned int RegisterQuestName(const string& name);
|
|
|
|
void RegisterQuest(const string & name, unsigned int idx);
|
|
unsigned int GetQuestIndexByName(const string& name);
|
|
const string& GetQuestNameByIndex(unsigned int idx);
|
|
|
|
void RequestSetEventFlag(const string& name, int value);
|
|
|
|
void SetEventFlag(const string& name, int value);
|
|
int GetEventFlag(const string& name);
|
|
void BroadcastEventFlagOnLogin(LPCHARACTER ch);
|
|
|
|
void SendEventFlagList(LPCHARACTER ch);
|
|
|
|
void Reload();
|
|
|
|
//void CreateAllButton(const string& quest_name, const string& button_name);
|
|
void SetError() { m_bError = true; }
|
|
void ClearError() { m_bError = false; }
|
|
bool IsError() { return m_bError; }
|
|
void WriteRunningStateToSyserr();
|
|
#ifndef __WIN32__
|
|
void QuestError(const char* func, int line, const char* fmt, ...);
|
|
#else
|
|
//void QuestError(const char* fmt, ...);
|
|
void QuestError(const char* func, int line, const char* fmt, ...);
|
|
#endif
|
|
|
|
void RegisterNPCVnum(DWORD dwVnum);
|
|
|
|
private:
|
|
LPDUNGEON m_pSelectedDungeon;
|
|
DWORD m_dwServerTimerArg;
|
|
|
|
map<pair<string, DWORD>, LPEVENT> m_mapServerTimer;
|
|
|
|
int m_iRunningEventIndex;
|
|
|
|
map<string, int> m_mapEventFlag;
|
|
|
|
void GotoSelectState(QuestState& qs);
|
|
void GotoPauseState(QuestState& qs);
|
|
void GotoEndState(QuestState& qs);
|
|
void GotoInputState(QuestState& qs);
|
|
void GotoConfirmState(QuestState& qs);
|
|
void GotoSelectItemState(QuestState& qs);
|
|
|
|
lua_State * L;
|
|
|
|
bool m_bNoSend;
|
|
|
|
set<unsigned int> m_registeredNPCVnum;
|
|
map<unsigned int, NPC> m_mapNPC;
|
|
map<string, unsigned int> m_mapNPCNameID;
|
|
map<string, unsigned int> m_mapTimerID;
|
|
|
|
QuestState * m_CurrentRunningState;
|
|
|
|
PCMap m_mapPC;
|
|
|
|
LPCHARACTER m_pCurrentCharacter;
|
|
LPCHARACTER m_pCurrentNPCCharacter;
|
|
LPCHARACTER m_pCurrentPartyMember;
|
|
PC* m_pCurrentPC;
|
|
|
|
string m_strScript;
|
|
|
|
int m_iCurrentSkin;
|
|
|
|
struct stringhash
|
|
{
|
|
size_t operator () (const string& str) const
|
|
{
|
|
const unsigned char * s = (const unsigned char*) str.c_str();
|
|
const unsigned char * end = s + str.size();
|
|
size_t h = 0;
|
|
|
|
while (s < end)
|
|
{
|
|
h *= 16777619;
|
|
h ^= (unsigned char) *(unsigned char *) (s++);
|
|
}
|
|
|
|
return h;
|
|
|
|
}
|
|
};
|
|
|
|
typedef std::unordered_map<string, int, stringhash> THashMapQuestName;
|
|
typedef std::unordered_map<unsigned int, vector<char> > THashMapQuestStartScript;
|
|
|
|
THashMapQuestName m_hmQuestName;
|
|
THashMapQuestStartScript m_hmQuestStartScript;
|
|
map<unsigned int, string> m_mapQuestNameByIndex;
|
|
|
|
bool m_bError;
|
|
|
|
public:
|
|
static bool ExecuteQuestScript(PC& pc, const string& quest_name, const int state, const char* code, const int code_size, vector<AArgScript*>* pChatScripts = NULL, bool bUseCache = true);
|
|
static bool ExecuteQuestScript(PC& pc, DWORD quest_index, const int state, const char* code, const int code_size, vector<AArgScript*>* pChatScripts = NULL, bool bUseCache = true);
|
|
|
|
|
|
// begin_other_pc_blcok, end_other_pc_block을 위한 객체들.
|
|
public:
|
|
void BeginOtherPCBlock(DWORD pid);
|
|
void EndOtherPCBlock();
|
|
bool IsInOtherPCBlock();
|
|
PC* GetOtherPCBlockRootPC();
|
|
private:
|
|
PC* m_pOtherPCBlockRootPC;
|
|
std::vector <DWORD> m_vecPCStack;
|
|
};
|
|
};
|
|
|
|
#endif
|