void __QuestEndComplete( int nPcId, int nNpcId, int& nGlobal, int nVal, int nQuestId ) { CUser* pUser = prj.GetUser( nPcId ); LPQUEST lpQuest = pUser->GetQuest( nQuestId ); #ifdef __VTN_TIMELIMIT // mulcom BEGIN100315 베트남 시간 제한 if( ::GetLanguage() == LANG_VTN ) { if( pUser->IsPlayer() == TRUE ) { if( pUser->m_nAccountPlayTime > MIN( 180 ) ) { pUser->AddDefinedText( TID_GAME_ERROR_QUEST_1 ); return; } } } // mulcom END100315 베트남 시간 제한 #endif // __VTN_TIMELIMIT // 퀘스트가 진행 중인 경우 if( lpQuest && pUser->IsCompleteQuest( nQuestId ) == FALSE && __IsEndQuestCondition( pUser, nQuestId ) ) { CMover* pMover = prj.GetMover( nNpcId ); if( __EndQuest( nPcId, nQuestId ) == TRUE ) pMover->m_pNpcProperty->RunDialog( "#questEndComplete", NULL, 0, nNpcId, nPcId, nQuestId ); #if __VER >= 15 // __IMPROVE_QUEST_INTERFACE __QuestEnd( nPcId, nNpcId, nGlobal, nQuestId, TRUE ); #else // __IMPROVE_QUEST_INTERFACE __QuestEnd( nPcId, nNpcId, nGlobal ); #endif // __IMPROVE_QUEST_INTERFACE } }
int __RemoveQuest( int nPcId, int nQuest ) { QuestProp* pQuestProp = prj.m_aPropQuest.GetAt( nQuest ); if( pQuestProp ) { CUser* pUser = prj.GetUser( nPcId ); LPQUEST pQuest = pUser->GetQuest( nQuest ); if( pQuest && pQuest->m_nState < 14 ) pUser->AddDefinedText( TID_EVE_CANCELQUEST, "\"%s\"", pQuestProp->m_szTitle ); pUser->RemoveQuest( nQuest ); pUser->AddRemoveQuest( nQuest ); // 시작시 변신을 했으면 퀘스트 삭제시 변신 해제시킨다. if( pQuest && pQuestProp->m_nBeginSetDisguiseMoverIndex ) { CUser* pUser = prj.GetUser( nPcId ); pUser->NoDisguise( NULL ); g_UserMng.AddNoDisguise( pUser ); } } return 1; }
void __QuestBeginYes( int nPcId, int nNpcId, int nQuestId ) { CUser* pUser = prj.GetUser( nPcId ); #ifdef __VTN_TIMELIMIT // mulcom BEGIN100315 베트남 시간 제한 if( ::GetLanguage() == LANG_VTN ) { if( pUser->IsPlayer() == TRUE ) { if( pUser->m_nAccountPlayTime > MIN( 180 ) ) { pUser->AddDefinedText( TID_GAME_ERROR_QUEST_1 ); return; } } } // mulcom END100315 베트남 시간 제한 #endif // __VTN_TIMELIMIT LPQUEST lpQuest = pUser->GetQuest( nQuestId ); if( __IsBeginQuestCondition( pUser, nQuestId ) && lpQuest == NULL && pUser->IsCompleteQuest( nQuestId ) == FALSE ) { __SayQuest( nPcId, nQuestId, QSAY_BEGIN_YES ); __RunQuest( nPcId, nNpcId, nQuestId ); CMover* pMover = prj.GetMover( nNpcId ); #if __VER >= 15 // __IMPROVE_QUEST_INTERFACE __RemoveAllKey( nPcId ); pMover->m_pNpcProperty->RunDialog( "#addKey", NULL, 0, nNpcId, nPcId, 0 ); LPQUEST lpQuestList; // 퀘스트 리스트 send vector<int> vecNewQuest; vector<int> vecNextQuest; vector<int> vecEndQuest; vector<int> vecCurrQuest; LPCHARACTER lpChar = prj.GetCharacter( pMover->m_szCharacterKey ); if( lpChar ) { for( int i = 0; i < lpChar->m_awSrcQuest.GetSize(); i++ ) { int nQuest = lpChar->m_awSrcQuest.GetAt( i ); lpQuestList = pUser->GetQuest( nQuest ); // new quest if( lpQuestList == NULL && pUser->IsCompleteQuest( nQuest ) == FALSE ) { // now if( __IsBeginQuestCondition( pUser, nQuest ) ) vecNewQuest.push_back( nQuest ); // next else if( __IsNextLevelQuest( pUser, nQuest ) ) vecNextQuest.push_back( nQuest ); } // current quest else if( lpQuestList && pUser->IsCompleteQuest( nQuest ) == FALSE ) { // complete if( __IsEndQuestCondition( pUser, nQuest ) ) vecEndQuest.push_back( nQuest ); // running else vecCurrQuest.push_back( nQuest ); } } // sort __QuestSort( vecNewQuest ); __QuestSort( vecNextQuest ); __QuestSort( vecEndQuest ); __QuestSort( vecCurrQuest ); // send for( DWORD i = 0; i < vecNewQuest.size(); ++i ) __AddQuestKey( nPcId, vecNewQuest[ i ], "QUEST_BEGIN", 0, TRUE ); for( DWORD i = 0; i < vecNextQuest.size(); ++i ) __AddQuestKey( nPcId, vecNextQuest[ i ], "QUEST_NEXT_LEVEL", 0, TRUE ); for( DWORD i = 0; i < vecEndQuest.size(); ++i ) __AddQuestKey( nPcId, vecEndQuest[ i ], "QUEST_END", 0, FALSE ); for( DWORD i = 0; i < vecCurrQuest.size(); ++i ) __AddQuestKey( nPcId, vecCurrQuest[ i ], "QUEST_END", 0, FALSE ); } #endif // __IMPROVE_QUEST_INTERFACE pMover->m_pNpcProperty->RunDialog( "#questBeginYes", NULL, 0, nNpcId, nPcId, nQuestId ); } }
void __QuestEnd( int nPcId, int nNpcId, int& nGlobal ) #endif // __IMPROVE_QUEST_INTERFACE { #if __VER >= 15 // __IMPROVE_QUEST_INTERFACE // 현재 진행 중인 퀘스트 중에서 현재 NPC가 처리해야될 퀘스트를 실행(자신일 수도 있음) CMover* pMover = prj.GetMover( nNpcId ); CUser* pUser = prj.GetUser( nPcId ); LPQUEST lpQuest; BOOL bNewQuest = FALSE; __RemoveAllKey( nPcId ); pMover->m_pNpcProperty->RunDialog( "#addKey", NULL, 0, nNpcId, nPcId, 0 ); // 퀘스트 리스트 send vector<int> vecNewQuest; vector<int> vecNextQuest; vector<int> vecEndQuest; vector<int> vecCurrQuest; LPCHARACTER lpChar = prj.GetCharacter( pMover->m_szCharacterKey ); if( lpChar ) { for( int i = 0; i < lpChar->m_awSrcQuest.GetSize(); i++ ) { int nQuest = lpChar->m_awSrcQuest.GetAt( i ); lpQuest = pUser->GetQuest( nQuest ); // new quest if( lpQuest == NULL && pUser->IsCompleteQuest( nQuest ) == FALSE ) { // now if( __IsBeginQuestCondition( pUser, nQuest ) ) { bNewQuest = TRUE; vecNewQuest.push_back( nQuest ); } // next else if( __IsNextLevelQuest( pUser, nQuest ) ) vecNextQuest.push_back( nQuest ); } // current quest else if( lpQuest && pUser->IsCompleteQuest( nQuest ) == FALSE && lpQuest->m_nState != QS_END ) { // complete if( __IsEndQuestCondition( pUser, nQuest ) ) vecEndQuest.push_back( nQuest ); // running else vecCurrQuest.push_back( nQuest ); } } // sort __QuestSort( vecNewQuest ); __QuestSort( vecNextQuest ); __QuestSort( vecEndQuest ); __QuestSort( vecCurrQuest ); // send for( DWORD i = 0; i < vecNewQuest.size(); ++i ) __AddQuestKey( nPcId, vecNewQuest[ i ], "QUEST_BEGIN", 0, TRUE ); for( DWORD i = 0; i < vecNextQuest.size(); ++i ) __AddQuestKey( nPcId, vecNextQuest[ i ], "QUEST_NEXT_LEVEL", 0, TRUE ); for( DWORD i = 0; i < vecEndQuest.size(); ++i ) __AddQuestKey( nPcId, vecEndQuest[ i ], "QUEST_END", 0, FALSE ); for( DWORD i = 0; i < vecCurrQuest.size(); ++i ) __AddQuestKey( nPcId, vecCurrQuest[ i ], "QUEST_END", 0, FALSE ); } BOOL bDialogText = TRUE; BOOL bCompleteCheck = TRUE; if( nQuestId ) { lpQuest = pUser->GetQuest( nQuestId ); QuestProp* pQuestProp = prj.m_aPropQuest.GetAt( nQuestId ); if( lpQuest && lpQuest->m_nState != QS_END && pQuestProp ) // 진행중인 퀘스트 선택 시 { bCompleteCheck = FALSE; if( !bButtOK ) // 퀘스트 목록을 선택하고 들어온 경우 { if( strcmpi( pQuestProp->m_szEndCondCharacter, pMover->m_szCharacterKey ) == 0 && __IsEndQuestCondition( pUser, nQuestId ) ) { __SayQuest( nPcId, nQuestId, QSAY_END_COMPLETE1 ); __SayQuest( nPcId, nQuestId, QSAY_END_COMPLETE2 ); __SayQuest( nPcId, nQuestId, QSAY_END_COMPLETE3 ); __AddAnswer( nPcId,"__OK__", "QUEST_END_COMPLETE", 0, nQuestId ); } else { __SayQuest( nPcId, nQuestId, QSAY_END_FAILURE1 ); __SayQuest( nPcId, nQuestId, QSAY_END_FAILURE2 ); __SayQuest( nPcId, nQuestId, QSAY_END_FAILURE3 ); __AddAnswer( nPcId,"__OK__", "QUEST_END_FAIL", 0, nQuestId ); } bDialogText = FALSE; } } } // 완료 가능한 퀘스트가 있는지 검사 if( bCompleteCheck ) { for( int i = 0; i < pUser->m_nQuestSize; ++i ) { lpQuest = &pUser->m_aQuest[i]; if( lpQuest ) { QuestProp* pQuestProp = prj.m_aPropQuest.GetAt( lpQuest->m_wId ); if( pQuestProp ) { if( strcmpi( pQuestProp->m_szEndCondCharacter, pMover->m_szCharacterKey ) == 0 && lpQuest->m_nState != QS_END ) { if( __IsEndQuestCondition( pUser, lpQuest->m_wId ) ) { __SayQuest( nPcId, lpQuest->m_wId, QSAY_END_COMPLETE1 ); __SayQuest( nPcId, lpQuest->m_wId, QSAY_END_COMPLETE2 ); __SayQuest( nPcId, lpQuest->m_wId, QSAY_END_COMPLETE3 ); __AddAnswer( nPcId,"__OK__", "QUEST_END_COMPLETE", 0, lpQuest->m_wId ); bDialogText = FALSE; break; } } } else WriteError( "__QuestEnd quest(%d) property null", lpQuest->m_wId ); } else WriteError( "__QuestEnd : user member quest(%d) null", i ); } } if( bDialogText ) { if( bNewQuest ) { if( vecNewQuest.size() == 1 && bCompleteCheck ) // 진행가능한 퀘스트가 하나면 바로 퀘스트 수락창 표시 __QuestBegin( nPcId, nNpcId, vecNewQuest[ 0 ] ); else pMover->m_pNpcProperty->RunDialog( "#yesQuest", NULL, 0, nNpcId, nPcId, 0 ); // 준비된 퀘스트가 있을 때의 인사말 } else pMover->m_pNpcProperty->RunDialog( "#noQuest", NULL, 0, nNpcId, nPcId, 0 ); // 준비된 퀘스트가 없을 때의 인사말 } #else // __IMPROVE_QUEST_INTERFACE // 현재 진행 중인 퀘스트 중에서 현재 NPC가 처리해야될 퀘스트를 실행(자신일 수도 있음) int nResult = 0; CMover* pMover = prj.GetMover( nNpcId ); CUser* pUser = prj.GetUser( nPcId ); LPQUEST lpQuest; __RemoveAllKey( nPcId ); while( nGlobal < pUser->m_nQuestSize ) { lpQuest = &pUser->m_aQuest[ nGlobal ]; nGlobal++; if( lpQuest ) { WORD nQuest = lpQuest->m_wId; QuestProp* pQuestProp = prj.m_aPropQuest.GetAt( nQuest ); if( pQuestProp ) { // 대화하고 있는 캐릭터와 현재 실행 중인 퀘스트가 같으면 그놈이 종결 조건을 판정하는 놈이다. if( strcmpi( pQuestProp->m_szEndCondCharacter, pMover->m_szCharacterKey ) == 0 ) { if( lpQuest->m_nState != QS_END ) { if( __IsEndQuestCondition( pUser, nQuest ) ) { __SayQuest( nPcId, nQuest, QSAY_END_COMPLETE1 ); __SayQuest( nPcId, nQuest, QSAY_END_COMPLETE2 ); __SayQuest( nPcId, nQuest, QSAY_END_COMPLETE3 ); __AddAnswer( nPcId,"__OK__", "QUEST_END_COMPLETE", 0, nQuest ); } else { __SayQuest( nPcId, nQuest, QSAY_END_FAILURE1 ); __SayQuest( nPcId, nQuest, QSAY_END_FAILURE2 ); __SayQuest( nPcId, nQuest, QSAY_END_FAILURE3 ); __AddAnswer( nPcId,"__OK__", "QUEST_END", 0, nQuest ); } nResult = 1; break; } } } else { WriteError( "__QuestEnd quest(%d) property null", nQuest ); } } else { WriteError( "__QuestEnd : user member quest(%d) null", nGlobal-1 ); } } // while( nGlobal < pUser->m_nQuestSize ) if( nResult == 0 ) { LPCHARACTER lpChar = prj.GetCharacter( pMover->m_szCharacterKey ); int anQuest[ 32 ]; for( int i = 0; i < lpChar->m_awSrcQuest.GetSize(); i++ ) { int nQuest = lpChar->m_awSrcQuest.GetAt( i ); lpQuest = pUser->GetQuest( nQuest ); if( __IsBeginQuestCondition( pUser, nQuest ) && lpQuest == NULL && pUser->IsCompleteQuest( nQuest ) == FALSE ) { anQuest[ nResult ] = nQuest; nResult++; } } // 가능한 퀘스트가 하나일 때는 바로 퀘스트 시작 if( nResult == 1 ) __QuestBegin( nPcId, nNpcId, anQuest[ 0 ] ); else { // 여러개일 경우는 키를 추가 for( i = 0; i < nResult; i++ ) __AddQuestKey( nPcId, anQuest[ i ], "QUEST_BEGIN" ); if ( nResult == 0 ) pMover->m_pNpcProperty->RunDialog( "#noQuest", &nResult, 0, nNpcId, nPcId, 0 ); // 준비된 퀘스트가 없을 때의 인사말 else pMover->m_pNpcProperty->RunDialog( "#yesQuest", &nResult, 0, nNpcId, nPcId, 0 ); // 준비된 퀘스트가 있을 때의 인사말 } } // 기타 대화를 위한 키를 추가한다. pMover->m_pNpcProperty->RunDialog( "#addKey", NULL, 0, nNpcId, nPcId, 0 ); #endif // __IMPROVE_QUEST_INTERFACE }