#include "StdAfx.h" #include "StatusScript.h" #include "./util/FileLoader.h" #include "./util/Tokenizer.h" #include "Parser.h" #include "Player_Common.h" #include "Lexer.h" #include "GameFileLexer.h" #ifdef _CLIENT #include "GameResourceManager.h" #endif cStatusScript* cStatusScript::mpStatusScript = NULL; cStatusScript::cStatusScript(void) { /// ½Ì±ÛÅæ if( !mpStatusScript ) { mpStatusScript = this; } } bool cStatusScript::Init() { /// ½ºÅÝ ±âº» ÇØ½¬¸Ê - ±âº» Á¾Á·±º 6°³ mpStatusBaseMap = new cPointerHashMap( 6 ); /// ½ºÅÝ Áõ°¡¼öÄ¡ ÇØ½¬¸Ê - Á÷¾÷±º 30°³ mpStatusMultiplMap = new cPointerHashMap( 50 ); /// ½ºÅÝ È®Àå ±âº» ÇØ½¬¸Ê - 3°³ mpStatusExtBaseMap = new cPointerHashMap( 20 ); /// ½ºÅÝ È®Àå Áõ°¡¼öÄ¡ ÇØ½¬¸Ê - 51°³ mpStatusExtMultiplMap = new cPointerHashMap( 20 ); /// ½ºÅÝ ±âº»Á¤º¸ ·Îµå if( !LoadStateBase() ) { assert(NULL); return false; } /// ½ºÅÝ Áõ°¡¼öÄ¡ ·Îµå if( !LoadStateMultipl() ) { assert(NULL); return false; } /// ½ºÅÝ È®Àå ±âº»Á¤º¸ ·Îµå if( !LoadStatusExtBase() ) { assert(NULL); return false; } /// ½ºÅÝ È®Àå Áõ°¡¼öÄ¡ ·Îµå if( !LoadStatusExtMultipl() ) { assert(NULL); return false; } /// µ¥¹ÌÁö°è»ê±â °è»ê ¼öÄ¡ ·Îµå if( !LoadDamageCalcNumerical() ) { assert(NULL); return false; } #ifndef _CLIENT /// Á÷¾÷¿¡ °ü·ÃÇÑ ¿¬°á Á¤º¸¸¦ »ý¼º if( !LoadPlayerJob() ) { assert(NULL); return false; } #endif return true; } void cStatusScript::Release() { RemovePlayerJobInfo(); if( mpStatusExtMultiplMap ) { float* pInfo = NULL; cPointerHashMap::cIterator i = mpStatusExtMultiplMap->Begin(); cPointerHashMap::cIterator end = mpStatusExtMultiplMap->End(); for( ; i != end; ++i ) { pInfo = (float*)(*i).mSecond; if( pInfo ) { delete [] pInfo; pInfo = NULL; } } mpStatusExtMultiplMap->Clear(); SAFE_DELETE( mpStatusExtMultiplMap ); } if( mpStatusExtBaseMap ) { cHashMap* pInfo = NULL; cPointerHashMap::cIterator i = mpStatusExtBaseMap->Begin(); cPointerHashMap::cIterator end = mpStatusExtBaseMap->End(); for( ; i != end; ++i ) { pInfo = (cHashMap*)(*i).mSecond; if( pInfo ) { pInfo->Clear(); delete pInfo; pInfo = NULL; } } mpStatusExtBaseMap->Clear(); SAFE_DELETE( mpStatusExtBaseMap ); } if( mpStatusMultiplMap ) { sStatusMultiplScript* pInfo = NULL; cPointerHashMap::cIterator i = mpStatusMultiplMap->Begin(); cPointerHashMap::cIterator end = mpStatusMultiplMap->End(); for( ; i != end; ++i ) { pInfo = (sStatusMultiplScript*)(*i).mSecond; if( pInfo ) { delete pInfo; pInfo = NULL; } } mpStatusMultiplMap->Clear(); SAFE_DELETE( mpStatusMultiplMap ); } if( mpStatusBaseMap ) { sStatusBaseScript* pInfo = NULL; cPointerHashMap::cIterator i = mpStatusBaseMap->Begin(); cPointerHashMap::cIterator end = mpStatusBaseMap->End(); for( ; i != end; ++i ) { pInfo = (sStatusBaseScript*)(*i).mSecond; if( pInfo ) { delete pInfo; pInfo = NULL; } } mpStatusBaseMap->Clear(); SAFE_DELETE( mpStatusBaseMap ); } } bool cStatusScript::LoadStateBase() { cFileLoader loader; cString pathName = "./Script/Resource/statusbase.txt"; if( loader.Open( pathName, true ) == false ) { assert( 0 && "failed to load statusbase.txt" ); return false; } cTokenizer tokenizer( loader.GetBufferPtr(), loader.GetSize(), " \t\r\n", pathName.Cstr() ); cString string; while( tokenizer.IsEnd() == false ) { /// Á÷¾÷±º ÄÚµå if( tokenizer.GetNext( &string ) == false ) { return false; } ePLAYER_JOB jobIndex = static_cast(string.ToInt()); /// Èû if( tokenizer.GetNext( &string ) == false ) { return false; } unsigned char str = static_cast(string.ToInt()); /// ¹Îø if( tokenizer.GetNext( &string ) == false ) { return false; } unsigned char dex = static_cast(string.ToInt()); /// ü·Â if( tokenizer.GetNext( &string ) == false ) { return false; } unsigned char con = static_cast(string.ToInt()); /// Áö´É if( tokenizer.GetNext( &string ) == false ) { return false; } unsigned char intelligence = static_cast(string.ToInt()); /// ÁöÇý if( tokenizer.GetNext( &string ) == false ) { return false; } unsigned char wis = static_cast(string.ToInt()); sStatusBaseScript* pList = new sStatusBaseScript; pList->mJobIndex = jobIndex; pList->mBaseStatus[ePLAYER_STATUS_STR] = str; pList->mBaseStatus[ePLAYER_STATUS_DEX] = dex; pList->mBaseStatus[ePLAYER_STATUS_CON] = con; pList->mBaseStatus[ePLAYER_STATUS_INT] = intelligence; pList->mBaseStatus[ePLAYER_STATUS_WIS] = wis; /// ÇØ½¬¿¡ ¸ó½ºÅÍ º°·Î ±â·Ï if( mpStatusBaseMap->Insert( pList->mJobIndex, pList ) == false ) { assert(NULL); return false; } } return true; } sStatusBaseScript* cStatusScript::GetStatusBaseInfo( unsigned long idx ) { sStatusBaseScript* statusBase; statusBase = (sStatusBaseScript*)mpStatusBaseMap->GetAt( idx ); if( !statusBase ) { return NULL; } return statusBase; } bool cStatusScript::LoadStateMultipl() { cFileLoader loader; cString pathName = "./Script/Resource/statusmultipl.txt"; if( loader.Open( pathName, true ) == false ) { assert( 0 && "failed to load statusmultipl.txt" ); return false; } cTokenizer tokenizer( loader.GetBufferPtr(), loader.GetSize(), " \t\r\n", pathName.Cstr() ); cString string; while( tokenizer.IsEnd() == false ) { /// Á÷¾÷±º ÄÚµå if( tokenizer.GetNext( &string ) == false ) { return false; } ePLAYER_JOB jobIndex = static_cast(string.ToInt()); /// Èû if( tokenizer.GetNext( &string ) == false ) { return false; } float str = string.ToFloat(); /// ¹Îø if( tokenizer.GetNext( &string ) == false ) { return false; } float dex = string.ToFloat(); /// ü·Â if( tokenizer.GetNext( &string ) == false ) { return false; } float con = string.ToFloat(); /// Áö´É if( tokenizer.GetNext( &string ) == false ) { return false; } float intelligence = string.ToFloat(); /// ÁöÇý if( tokenizer.GetNext( &string ) == false ) { return false; } float wis = string.ToFloat(); sStatusMultiplScript * pList = new sStatusMultiplScript; pList->mJobIndex = jobIndex; pList->mBaseStatus[ePLAYER_STATUS_STR] = str; pList->mBaseStatus[ePLAYER_STATUS_DEX] = dex; pList->mBaseStatus[ePLAYER_STATUS_CON] = con; pList->mBaseStatus[ePLAYER_STATUS_INT] = intelligence; pList->mBaseStatus[ePLAYER_STATUS_WIS] = wis; /// ÇØ½¬¿¡ ±â·Ï if( mpStatusMultiplMap->Insert( pList->mJobIndex, pList ) == false ) { assert(NULL); return false; } } return true; } sStatusMultiplScript* cStatusScript::GetStatusMultiplInfo(unsigned long idx) { sStatusMultiplScript* statusMultipl; statusMultipl = (sStatusMultiplScript*)mpStatusMultiplMap->GetAt( idx ); if( !statusMultipl ) { return NULL; } return statusMultipl; } bool cStatusScript::LoadStatusExtBase() { cFileLoader loader; cString pathName = "./Script/Resource/statusextbase.txt"; if( loader.Open( pathName, true ) == false ) { assert( 0 && "failed to load statusextbase.txt" ); return false; } cTokenizer tokenizer( loader.GetBufferPtr(), loader.GetSize(), " \t\r\n", pathName.Cstr() ); cString str; cHashMap* pStatusExt = NULL; while( tokenizer.IsEnd() == false ) { /// È®Àå ½ºÅÝ ±¸ºÐ if( tokenizer.GetNext( &str ) == false ) { return false; } ePLAYER_STATUS_EXT statusExtBase = (ePLAYER_STATUS_EXT)str.ToInt(); /// Á÷¾÷ ±¸ºÐ if( tokenizer.GetNext( &str ) == false ) { return false; } ePLAYER_JOB job = (ePLAYER_JOB)str.ToInt(); /// ±âº»°ª if( tokenizer.GetNext( &str ) == false ) { return false; } float defaultValue = str.ToFloat(); pStatusExt = (cHashMap*)mpStatusExtBaseMap->GetAt( statusExtBase ); if( pStatusExt == NULL ) { pStatusExt = new cHashMap; if( mpStatusExtBaseMap->Insert( statusExtBase, pStatusExt ) == NULL ) { assert(NULL); return false; } } if( pStatusExt->Insert( job, defaultValue ) == NULL ) { assert(NULL); return false; } } return true; } float cStatusScript::GetStatusExtBaseInfo( unsigned long statusExt, unsigned long jobCode ) { cHashMap* jobDefaultHashMap = NULL; jobDefaultHashMap = (cHashMap*)mpStatusExtBaseMap->GetAt( statusExt ); if( jobDefaultHashMap == NULL ) { return 0.0f; } cHashMap::cIterator find = jobDefaultHashMap->Find( jobCode ); cHashMap::cIterator end = jobDefaultHashMap->End(); if( find == end ) { return SearchParentStatusExtbaseInfo( statusExt, jobCode ); } return (*find).mSecond; } float cStatusScript::SearchParentStatusExtbaseInfo( unsigned long statusExt, unsigned long jobcode ) { // /// »óÀ§Á÷¾÷ °Ë»ç // #ifdef _CLIENT // tArray* parentJob = GAMERESOURCEMAN->GetParentJob( jobcode ); // if( parentJob && parentJob->GetSize() > 0 ) // { // for( unsigned int i=parentJob->GetSize()-1; i >=0; --i ) // { // float statusValue = (float)GetStatusExtBaseInfo( statusExt, (*parentJob)[i] ); // if( FloatToInt(statusValue) != 0 ) // return statusValue; // } // } // #else // tArray* parentJob = GetParentJob( jobcode ); // if( parentJob && parentJob->GetSize() > 0 ) // { // for( unsigned int i=parentJob->GetSize()-1; i >=0; --i ) // { // float statusValue = (float)GetStatusExtBaseInfo( statusExt, (*parentJob)[i] ); // if( FloatToInt(statusValue) != 0 ) // return statusValue; // } // } // #endif return 0.0f; } bool cStatusScript::LoadStatusExtMultipl() { cFileLoader loader; cString pathName = "./Script/Resource/statusextmultipl.txt"; if( loader.Open( pathName, true ) == false ) { assert( 0 && "failed to load statusextmultipl.txt" ); return false; } cTokenizer tokenizer( loader.GetBufferPtr(), loader.GetSize(), " \t\r\n", pathName.Cstr() ); cString str; float* statusExtMultiplScript = NULL; while( tokenizer.IsEnd() == false ) { /// ±¸ºÐ if( tokenizer.GetNext( &str ) == false ) { return false; } eEXT_MULTIPL statusExtBase = (eEXT_MULTIPL)(str.ToInt()); /// µî·ÏµÈ °ªÀÌ ÀÖ´ÂÁö üũ statusExtMultiplScript = (float*)mpStatusExtMultiplMap->GetAt( statusExtBase ); /// µî·ÏµÈ °ª(¹è¿­Æ÷ÀÎÅÍ)ÀÌ ¾øÀ¸¸é ½Å±Ô »ý¼º if( statusExtMultiplScript == NULL ) { statusExtMultiplScript = new float[ePLAYER_STATUS_LEVEL_MAX]; memset( statusExtMultiplScript, 0, sizeof(float[ePLAYER_STATUS_LEVEL_MAX]) ); /// ÇØ½¬¿¡ ±â·Ï if( mpStatusExtMultiplMap->Insert( statusExtBase, statusExtMultiplScript ) == false ) { assert(NULL); return false; } } /// Ç׸ñ[¹è¿­¹øÈ£] if( tokenizer.GetNext( &str ) == false ) { return false; } ePLAYER_STATUS type = static_cast(str.ToInt()); /// ºñÁß if( tokenizer.GetNext( &str ) == false ) { return false; } float importance = str.ToFloat(); if( ePLAYER_STATUS_LEVEL < type ) { assert(NULL); return false; } statusExtMultiplScript[type]= importance; } return true; } float cStatusScript::GetStatusExtMultiplInfo( eEXT_MULTIPL statusExtBase, ePLAYER_STATUS type ) { float* statusExtMultipl = (float*)mpStatusExtMultiplMap->GetAt( statusExtBase ); if( statusExtMultipl == NULL ) { return 0.0f; } if( ePLAYER_STATUS_LEVEL < type ) { assert(NULL); return 0.0f; } return statusExtMultipl[type]; } bool cStatusScript::LoadDamageCalcNumerical() { cFileLoader loader; cString pathName = "./Script/Resource/DamageCalc.txt"; if( loader.Open( pathName, true ) == false ) { assert( 0 && "failed to load DamageCalc.txt" ); return false; } cTokenizer tokenizer( loader.GetBufferPtr(), loader.GetSize(), " \t\r\n", pathName.Cstr() ); cString str; while( tokenizer.IsEnd() == false ) { /// ¹øÈ£ if( tokenizer.GetNext( &str ) == false ) { return false; } unsigned short num = static_cast(str.ToInt()); /// °ª if( tokenizer.GetNext( &str ) == false ) { return false; } float value = str.ToFloat(); /// ÇØ½¬¿¡ ±â·Ï if( mDamageCalcNumericalMap.Insert( num, value ) == false ) { assert(0); return false; } } return true; } float cStatusScript::GetDamageCalcNumericalInfo(unsigned long idx) { cHashMap::cIterator i = mDamageCalcNumericalMap.Find( idx ); if( i == mDamageCalcNumericalMap.End() ) { assert( NULL ); return 0.0f; } return (float)((*i).mSecond); } /// ÁÖÀÇ »çÇ× : PlayerÀÇ Á÷¾÷ ¿¬°áÀ» »ý¼ºÇÑ´Ù. bool cStatusScript::LoadPlayerJob() { #ifndef _CLIENT /// ÆÄÀÏ ¿­±â cFileLoader loader; if( loader.Open( _T("./Script/Resource/PlayerJobTree.txt"), true ) == false ) { return false; } /// cToken token; cGameFileLexer lexer( loader.GetBufferPtr(), loader.GetSize() ); cParser parser( &lexer, _T("./Script/Resource/PlayerJobTree.txt") ); while( lexer.IsEnd() == false ) { lexer.GetNextToken( &token ); switch( token.mType ) { case eTOKEN_ERROR: return false; case eTOKEN_NULL: continue; case eTOKEN_JOBINFO: { if( LoadPlayerJobInfo(parser) == false ) { assert(0); return false; } } break; case eTOKEN_JOBTREE: { unsigned int depth = parser.ParseInt(); if( LoadPlayerJobTree(parser, depth) == false ) { assert(0); return false; } } break; default: assert( 0 && "invalid token" ); return false; } } #endif return true; } bool cStatusScript::LoadPlayerJobInfo( cParser& parser ) { parser; #ifndef _CLIENT if( parser.ExpectTokenString( _T( "{" ) ) == false ) { assert( 0 && "wrong script" ); return false; } cToken token; cLexer* lexer = parser.GetLexer(); while( lexer->GetNextToken( &token ) ) { if( token == _T( "}" ) ) break; switch( token.mType ) { case eTOKEN_ERROR: return false; case eTOKEN_NULL: continue; case eTOKEN_INT: { unsigned long jobIdx = (unsigned long)token.ToInt(); unsigned char race = (unsigned char)parser.ParseInt(); unsigned int jobNameIdx = parser.ParseInt(); unsigned int jobIconIdx = parser.ParseInt(); jobIdx; race; jobNameIdx; jobIconIdx; } break; default: assert( 0 && "invalid token" ); return false; } } #endif return true; } bool cStatusScript::LoadPlayerJobTree( cParser& parser, unsigned int depth ) { parser; depth; #ifndef _CLIENT if( parser.ExpectTokenString( _T( "{" ) ) == false ) { assert( 0 && "wrong script" ); return false; } cToken token; cLexer* lexer = parser.GetLexer(); while( lexer->GetNextToken( &token ) ) { if( token == _T( "}" ) ) { break; } switch( token.mType ) { case eTOKEN_ERROR: return false; case eTOKEN_NULL: continue; case eTOKEN_INT: { cJobIndexArray tempArray; /// ±âº» Á÷¾÷±ºÀ» ÀоîµéÀδÙ. unsigned long jobIdx = token.ToInt(); tempArray.PushBack(jobIdx); /// ÃÖÁ¾ Â÷¼ö±îÁöÀÇ Á÷¾÷±ºÀ» ¸ðµÎ ´ã´Â´Ù. for( unsigned int i=0; i0; --i ) { /// ÃÖÁ¾ ÀüÁ÷Â÷¼öÀÇ Á÷¾÷ À妽º¸¦ key·Î »ç¿ë unsigned long jobIdx = tempArray[i]; /// »õ·Î¿î Á÷¾÷¿¬°áÀ» »ý¼º cJobIndexArray* newJobTree = new cJobIndexArray; /// Â÷¼ö±îÁöÀÇ ºÎ¸ð Á÷¾÷µéÀ» ´ã´Â´Ù. for( int k=0 ; kPushBack( parentJob ); } /// ÂüÁ¶ ¸ÊÀ» ±¸¼ºÇÑ´Ù. if( mJobTree.Insert( jobIdx, newJobTree) == false ) { assert(0); SAFE_DELETE(newJobTree); } } } } break; default: assert( 0 && "invalid token" ); return false; } } #endif return true; } void cStatusScript::RemovePlayerJobInfo() { cPointerHashMap::cIterator i = mJobTree.Begin(); cPointerHashMap::cIterator end = mJobTree.End(); for( ; i != end; ++i ) { cJobIndexArray* pArray = (cJobIndexArray*)((*i).mSecond); SAFE_DELETE(pArray); } mJobTree.Clear(); } tArray* cStatusScript::GetParentJob( unsigned long currentJob ) { cJobIndexArray* pArray = (cJobIndexArray*)mJobTree.GetAt( currentJob ); if( pArray ) { return pArray; } return 0; } unsigned int cStatusScript::GetJobStep( unsigned long jobIdx ) { tArray* pArray = GetParentJob( jobIdx ); if( pArray == 0 ) { return 0; } return pArray->GetSize(); }