diff --git a/src/game/input.h b/src/game/input.h index 6980b2c..f0ca4f7 100644 --- a/src/game/input.h +++ b/src/game/input.h @@ -132,6 +132,7 @@ class CInputMain : public CInputProcessor void QuestInputString(LPCHARACTER ch, const void * pvData); void QuestConfirm(LPCHARACTER ch, const void* pvData); + void QuestCancel(LPCHARACTER ch); void Target(LPCHARACTER ch, const char * pcData); void Warp(LPCHARACTER ch, const char * pcData); void SafeboxCheckin(LPCHARACTER ch, const char * c_pData); diff --git a/src/game/input_main.cpp b/src/game/input_main.cpp index 6942fbc..53add09 100644 --- a/src/game/input_main.cpp +++ b/src/game/input_main.cpp @@ -2056,6 +2056,12 @@ void CInputMain::QuestConfirm(LPCHARACTER ch, const void* c_pData) } } +void CInputMain::QuestCancel(LPCHARACTER ch) +{ + sys_log(0, "QuestCancel from %s pid %u", ch->GetName(), ch->GetPlayerID()); + quest::CQuestManager::Instance().Cancel(ch->GetPlayerID()); +} + void CInputMain::Target(LPCHARACTER ch, const char * pcData) { TPacketCGTarget * p = (TPacketCGTarget *) pcData; @@ -3272,6 +3278,10 @@ int CInputMain::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) QuestConfirm(ch, c_pData); break; + case HEADER_CG_QUEST_CANCEL: + QuestCancel(ch); + break; + case HEADER_CG_TARGET: Target(ch, c_pData); break; diff --git a/src/game/packet.h b/src/game/packet.h index 85bcf56..6b8b766 100644 --- a/src/game/packet.h +++ b/src/game/packet.h @@ -34,6 +34,7 @@ enum HEADER_CG_SCRIPT_ANSWER = 29, HEADER_CG_QUEST_INPUT_STRING = 30, HEADER_CG_QUEST_CONFIRM = 31, + HEADER_CG_QUEST_CANCEL = 32, HEADER_CG_SHOP = 50, HEADER_CG_FLY_TARGETING = 51, @@ -806,6 +807,11 @@ typedef struct command_quest_confirm uint32_t requestPID; } TPacketCGQuestConfirm; +typedef struct command_quest_cancel +{ + uint8_t header; +} TPacketCGQuestCancel; + /* * 서버 측에서 보내는 패킷 */ diff --git a/src/game/packet_info.cpp b/src/game/packet_info.cpp index b7fa9a1..1fcae85 100644 --- a/src/game/packet_info.cpp +++ b/src/game/packet_info.cpp @@ -174,6 +174,7 @@ CPacketInfoCG::CPacketInfoCG() Set(HEADER_CG_SCRIPT_BUTTON, sizeof(TPacketCGScriptButton), "ScriptButton", true); Set(HEADER_CG_QUEST_INPUT_STRING, sizeof(TPacketCGQuestInputString), "QuestInputString", true); Set(HEADER_CG_QUEST_CONFIRM, sizeof(TPacketCGQuestConfirm), "QuestConfirm", true); + Set(HEADER_CG_QUEST_CANCEL, sizeof(TPacketCGQuestCancel), "QuestCancel", true); Set(HEADER_CG_MOVE, sizeof(TPacketCGMove), "Move", true); Set(HEADER_CG_SYNC_POSITION, sizeof(TPacketCGSyncPosition), "SyncPosition", true); diff --git a/src/game/questmanager.cpp b/src/game/questmanager.cpp index b9a0bff..95ba973 100644 --- a/src/game/questmanager.cpp +++ b/src/game/questmanager.cpp @@ -381,6 +381,23 @@ namespace quest } } + void CQuestManager::Cancel(unsigned int pc) + { + PC * pPC = GetPC(pc); + + if (pPC && pPC->IsRunning()) + { + sys_log(0, "QUEST: Dialog cancelled by player %u, cleaning up quest state (quest: %s)", pc, pPC->GetCurrentQuestName().c_str()); + + CloseState(*pPC->GetRunningQuestState()); + pPC->CancelRunning(); + } + else + { + sys_log(0, "QUEST: Cancel requested for player %u but no quest is running", pc); + } + } + /////////////////////////////////////////////////////////////////////////////////////////// // // Quest Event 관련 diff --git a/src/game/questmanager.h b/src/game/questmanager.h index 3340dc0..ebef9ea 100644 --- a/src/game/questmanager.h +++ b/src/game/questmanager.h @@ -114,6 +114,7 @@ namespace quest void SelectItem(unsigned int pc, unsigned int selection); void LogoutPC(LPCHARACTER ch); + void Cancel(unsigned int pc); void DisconnectPC(LPCHARACTER ch); QuestState * GetCurrentState() { return m_CurrentRunningState; }