#include "stdafx.h" #include "SSkillDB.h" #include #include #include "KTypes.h" #include #include #include "SkillBaseFile.h" #include "SNetMessage.h" #include //#include "Util.h" #include "KResourceManager.h" #include "Slog.h" #include "SJobDB.h" #include "SDebug_Util.h" #include "AR_DIFF.h" extern HWND g_hWnd; SSkillDB::SSkillDB() { Init(); } SSkillDB::~SSkillDB() { Destroy(); } /// 2011.05.27 AR_TIME -> long - prodongi long SSkillDB::GetCastingTime( int nSkillID, int nSkill_lv ) { SkillBaseEx * pData = GetSkillData( nSkillID ); if( pData ) { return pData->GetCastDelay( nSkill_lv ); } return 0; } bool SSkillDB::IsNeedTarget( int nSkillID ) { SkillBaseEx * pData = GetSkillData( nSkillID ); if( pData ) { return pData->IsNeedTarget(); } return true; } SkillBaseEx * SSkillDB::GetSkillData( int nSkillID ) { SkillBaseEx * pFindSkill = NULL; if( m_hashSkill.lookup( nSkillID, pFindSkill ) == false ) { return NULL; } else { return pFindSkill; } return NULL; } int SSkillDB::GetToolTipID( int nSkillID ) { SkillBaseEx * pSkill = GetSkillData( nSkillID ); if( pSkill ) { return pSkill->GetToolTipID(); } return 0; } const char * SSkillDB::GetIconName( int nSkillID ) { SkillBaseEx * pSkill = GetSkillData( nSkillID ); if( pSkill ) { return pSkill->GetIconName(); } return "NotFound"; } int SSkillDB::GetIconID( int nSkillID ) { SkillBaseEx * pSkill = GetSkillData( nSkillID ); if( pSkill ) { return pSkill->GetIconID(); } return 0; } int SSkillDB::GetStringID( int nSkillID ) { SkillBaseEx * pSkill = GetSkillData( nSkillID ); if( pSkill ) { return pSkill->GetNameID(); } return 0; } void SSkillDB::Init() { Load(); } void SSkillDB::Destroy() { SkillBaseEx* pSkill = NULL; bool res; res = m_hashSkill.get_first_value( pSkill ); while ( res ) { if ( pSkill != NULL ) { delete pSkill; } res = m_hashSkill.get_next_value( pSkill ); } m_hashSkill.clear(); } inline bool GetRecordSetFromResource( XRecordSet< wchar_t > & rs, const char *szFileName ) { KStream * pRes1 = KFileManager::Instance().CreateStreamFromResource( szFileName ); if( !pRes1 ) return false; char *p = (char*)pRes1->GetMappedPtr( 0 ) + 2; basic_string< wchar_t > tstr( (wchar_t*)p, pRes1->GetLength()/2 - 1 ); basic_stringstream< wchar_t > temp( tstr ); DWORD tm = GetSafeTickCount(); rs.LoadFrom( temp ); //_oprint( "SkillLoad : %dms\n", GetSafeTickCount() - tm ); 릴리즈모드에서는 보통 50~100ms 안에 끝남. KFileManager::Instance().DeleteStream( pRes1 ); return true; } void SSkillDB::Load() { // 텍스트 파일에서 바로 읽는것 만들다 말았음. -_- by Testors bool bNewLoader = false; if( bNewLoader ) { XRecordSet< wchar_t > recordset; if( GetRecordSetFromResource( recordset, "SkillResource.txt" ) ) { return; } } //New Data KStream * pRes1 = KFileManager::Instance().CreateStreamFromResource( "db_skill.rdb" ); if( !pRes1 ) return; GAME_DB db_hdr; pRes1->Read( &db_hdr, sizeof(db_hdr) ); //// RDB 와 Header의 사이즈 비교. ////// TEST //SkillBaseEx testEX; //char sdfdsf[256] = { NULL, }; //sprintf( sdfdsf, "size : %d, offset : %d", testEX.GetRealSize(), testEX.GetOffset() ); //::MessageBox( g_hWnd, sdfdsf, "Error", MB_OK ); //int fileSize = pRes1->Size() - ( STR_DATE_BUFFER + sizeof( int ) ); //char sstr[512] = { NULL, }; //sprintf( sstr, "%d , %d, %d", sizeof(SkillBase), sizeof(SkillBaseEx), db_hdr.nCount ); //::MessageBox( g_hWnd, sstr, "Error", MB_OK ); ////int headerSize = sizeof(SkillBaseEx) * db_hdr.nCount; //int headerSize = 833 * db_hdr.nCount; //if( fileSize != headerSize ) //{ // char str[512] = { NULL, }; // sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ", // db_hdr.szDate, // __FILE__, // fileSize, // headerSize // ); // // ::MessageBox( g_hWnd, str, "Error", MB_OK ); // // if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES ) // { // exit( 1 ); // } //} ////// RDB 와 Header의 사이즈 비교. //int fileSize = pRes1->Size() - ( STR_DATE_BUFFER + sizeof( int ) ); //int headerSize = sizeof(SkillBaseEx) * db_hdr.nCount; // //if( fileSize != headerSize ) //{ // char str[512] = { NULL, }; // sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ", // db_hdr.szDate, // __FILE__, // fileSize, // headerSize // ); // // ::MessageBox( g_hWnd, str, "Error", MB_OK ); // // if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES ) // { // exit( 1 ); // } //} for( int i(0); db_hdr.nCount>i; i++ ) { SkillBaseEx * pSkillBase = new SkillBaseEx; pRes1->Read( pSkillBase, sizeof(SkillBaseEx) ); SkillBaseEx * pFindSkill = NULL; if( m_hashSkill.lookup( pSkillBase->GetID(), pFindSkill ) == false ) { /* #ifdef _DEV if(KSpriteManager::GetManager()->GetResSpriteAni("ui_frame.spr", pSkillBase->GetIconName() ) == NULL) { GetLog().DebugLog( "SkillDB - spr에 icon 파일이 등록되지 않았습니다 - id:%d / icon id:%d / %s \n", pSkillBase->GetID(), pSkillBase->GetIconID(), pSkillBase->GetIconName() ); } #endif*/ //이유는 알 수 없으나 위 코드가 있으면 리소스를 제대로 읽지 못함 2009.07.06. sfreer m_hashSkill.add( pSkillBase->GetID(), pSkillBase ); } else { //_oprint( "!!!!Data Error Item Code 가 중복되었습니다.!!!! %d\n", pSkillBase->GetID() ); // GetLog().DebugLog( "!!!!Data Error Skill Code 가 중복되었습니다.!!!! %d\n", pSkillBase->GetID() ); // assert(0); //기획팀에 알려 주세여. 바로 수정 해야 합니다. delete pSkillBase; } } KFileManager::Instance().DeleteStream( pRes1 ); #ifdef _COUNTRY_ME_ /////////////////////////////////////////////////// // EXCEPTION/////////////////////////////////////// for (int i=0;iuid ); if (pSkill==NULL) continue; int type = ps->type; if (type==0) continue; float old_value = ps->old_value; float new_value = ps->new_value; //float cmp_value = 0.0f; //if (type >= 1 && type <=20) cmp_value = pSkill->var[type-1]; //if (type == 21) cmp_value = pSkill->delay_cooltime; //if (type == 22) cmp_value = pSkill->delay_cast_per_skl; //if (old_value!= cmp_value) // _cprint( "g_pException_AR:%d type:%d old:%.2f(%.2f) new:%.2f\n", ps->uid,type,old_value,cmp_value,new_value); if (type >= 1 && type <=20) pSkill->var[type-1] = new_value; else if (type == 21) pSkill->delay_cooltime = new_value*100; else if (type == 22) pSkill->state_second_per_skl= new_value*100; } for (int i=0;iuid ); if (pSkill==NULL) continue; int type = ps->type; if (type==0) continue; float old_value = ps->old_value; float new_value = ps->new_value; //float cmp_value = 0.0f; //if (type >= 1 && type <=20) cmp_value = pSkill->var[type-1]; //if (type == 21) cmp_value = pSkill->delay_cooltime; //if (type == 22) cmp_value = pSkill->delay_cast_per_skl; //if (old_value!= cmp_value) // _cprint( "g_pException_921:%d type:%d old:%.2f(%.2f) new:%.2f\n", ps->uid,type,old_value,cmp_value,new_value); if (type >= 1 && type <=20) pSkill->var[type-1] = new_value; else if (type == 21) pSkill->delay_cooltime = new_value*100; else if (type == 22) pSkill->state_second_per_skl= new_value*100; } #endif } SSkillDB* SSkillDB::m_pThis = NULL; SSkillDB & GetSkillDB() { if( NULL == SSkillDB::m_pThis ) SSkillDB::m_pThis = new SSkillDB; return *SSkillDB::m_pThis; // static SSkillDB skilldb; // return skilldb; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //스킬 트리 Display~ SSkillTreeDisplayDB::SSkillTreeDisplayDB() { Init(); } SSkillTreeDisplayDB::~SSkillTreeDisplayDB() { Destroy(); } SSkillTreeDisplayDB::SKILL_TREE::~SKILL_TREE() { for( unsigned int i(0); job_tree_list.size()>i; i++ ) { delete job_tree_list[i]; } job_tree_list.clear(); } void SSkillTreeDisplayDB::Init() { Load(); } void SSkillTreeDisplayDB::Destroy() { for( unsigned int i(0); tree_list.size()>i; i++ ) { delete tree_list[i]; } tree_list.clear(); } void SSkillTreeDisplayDB::GetSkillTree( int nJobID, vector& skill_tree ) { for( unsigned int i(0); tree_list.size()>i; i++ ) { SKILL_TREE* pData = tree_list[i]; if( pData->nJobID == nJobID ) { for( unsigned int n(0); pData->job_tree_list.size()>n; n++ ) { skill_tree.push_back( pData->job_tree_list[n] ); } break; } } } void SSkillTreeDisplayDB::addTreeData( const SkillTreeDisplay* pNewData ) { for( unsigned int i(0); tree_list.size()>i; i++ ) { SKILL_TREE* pData = tree_list[i]; if( pData->nJobID == pNewData->job_id ) { SkillTreeDisplay* pSkillData = new SkillTreeDisplay; pSkillData->job_id = pNewData->job_id; pSkillData->slot_v = pNewData->slot_v; pSkillData->skill1_id = pNewData->skill1_id; pSkillData->skill2_id = pNewData->skill2_id; pSkillData->skill3_id = pNewData->skill3_id; pSkillData->skill4_id = pNewData->skill4_id; pSkillData->skill5_id = pNewData->skill5_id; pData->job_tree_list.push_back( pSkillData ); assert( pData->job_tree_list.size() <= 9 && "한 직업당 스킬 슬롯이 9개 이상임" ); return; } } // _performance_print( "%d JOB : %d\n", tree_list.size(), pNewData->job_id ); SKILL_TREE* pSkill_tree = new SKILL_TREE; pSkill_tree->nJobID = pNewData->job_id; SkillTreeDisplay* pSkillData = new SkillTreeDisplay; pSkillData->job_id = pNewData->job_id; pSkillData->slot_v = pNewData->slot_v; pSkillData->skill1_id = pNewData->skill1_id; pSkillData->skill2_id = pNewData->skill2_id; pSkillData->skill3_id = pNewData->skill3_id; pSkillData->skill4_id = pNewData->skill4_id; pSkillData->skill5_id = pNewData->skill5_id; pSkill_tree->job_tree_list.push_back( pSkillData ); tree_list.push_back( pSkill_tree ); } void SSkillTreeDisplayDB::Load() { //New Data KStream * pRes1 = KFileManager::Instance().CreateStreamFromResource( "db_SkillTreeDisplay.rdb" ); if( !pRes1 ) return; GAME_DB db_hdr; pRes1->Read( &db_hdr, sizeof(db_hdr) ); //// RDB 와 Header의 사이즈 비교. //int fileSize = pRes1->Size() - ( STR_DATE_BUFFER + sizeof( int ) ); //int headerSize = sizeof(SkillTreeDisplay) * db_hdr.nCount; // //if( fileSize != headerSize ) //{ // char str[512] = { NULL, }; // sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ", // db_hdr.szDate, // __FILE__, // fileSize, // headerSize // ); // // ::MessageBox( g_hWnd, str, "Error", MB_OK ); // // if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES ) // { // exit( 1 ); // } //} for( int i(0); db_hdr.nCount>i; i++ ) { SkillTreeDisplay skilltreedisplay; pRes1->Read( &skilltreedisplay, sizeof(skilltreedisplay) ); addTreeData( &skilltreedisplay ); } KFileManager::Instance().DeleteStream( pRes1 ); } SSkillTreeDisplayDB & GetSkillTreeDisplayDB() { static SSkillTreeDisplayDB skillTreeDisplayDB; return skillTreeDisplayDB; } //----------------------------------------------------------------------------------------------------------------- // 스킬 트리 DB Struct //----------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------- // 생성자 //----------------------------------------------------------------------------------------------------------------- SSkillTreeDB::SSkillTreeDB() { Init(); } //----------------------------------------------------------------------------------------------------------------- // 파괴자 //----------------------------------------------------------------------------------------------------------------- SSkillTreeDB::~SSkillTreeDB() { auto pos = m_mapSkillTreeList.begin(); auto end = m_mapSkillTreeList.end(); for( ; pos != end; ++pos ) { delete pos->second; } m_mapSkillTreeList.clear(); } //----------------------------------------------------------------------------------------------------------------- // 초기화 //----------------------------------------------------------------------------------------------------------------- void SSkillTreeDB::Init() { Load(); } //----------------------------------------------------------------------------------------------------------------- // RDB 파일 불러오기 //----------------------------------------------------------------------------------------------------------------- void SSkillTreeDB::Load() { KStream * pRes1 = KFileManager::Instance().CreateStreamFromResource( "db_skilltree.rdb" ); if( NULL == pRes1 ) { SLOG( "[SSkillTreeDB] Create Stream Failed - [db_skilltree.rdb]" ); assert( NULL ); return ; } GAME_DB db_hdr; pRes1->Read( &db_hdr, sizeof( db_hdr ) ); for( int i(0); db_hdr.nCount>i; i++ ) { std::vector< SkillTreeEx >* _skillList = NULL; int nTreeSize = 0; pRes1->Read( &nTreeSize, sizeof( nTreeSize ) ); if( nTreeSize > 0 ) { _skillList = new std::vector< SkillTreeEx >(); for( int nCount = 0; nTreeSize > nCount; nCount++ ) { SkillTree SkillTreeTemp; pRes1->Read( &SkillTreeTemp, sizeof( SkillTreeTemp ) ); SkillTreeEx stSkillTreeEx( SkillTreeTemp ); if( NULL != SkillTreeTemp.skill_group_id ) stSkillTreeEx.bIsRandomSkill = true; _skillList->push_back( stSkillTreeEx ); } m_mapSkillTreeList.insert( std::make_pair( _skillList->front().skill_tree_id, _skillList ) ); } } KFileManager::Instance().DeleteStream( pRes1 ); } //----------------------------------------------------------------------------------------------------------------- // 스킬 ID를 넘겨 주면, 갖고 있는 모든 Job ID를 돌려 준다. //----------------------------------------------------------------------------------------------------------------- void SSkillTreeDB::GetJobList_hasSkill( int nSkillID, vector & jobList ) { auto vJobList = GetJobDB().GetJobAllData(); auto pos = vJobList.cbegin(); auto end = vJobList.cend(); for( ; pos != end; ++pos ) { const JobInfoEx* pJob = (*pos); auto pSkillTree = GetSkillTreeData( pJob->skill_tree_id ); auto tree_pos = pSkillTree->cbegin(); auto tree_end = pSkillTree->cend(); for( ; tree_pos != tree_end; ++tree_pos ) { if( (*tree_pos).skill_id == nSkillID ) { bool need_add = true; for( size_t i(0); iid ) // TODO { need_add = false; break; } } if( need_add == true ) { jobList.push_back( pJob->id ); } break; } } } } //----------------------------------------------------------------------------------------------------------------- // 스킬 트리 데이터 얻기 //----------------------------------------------------------------------------------------------------------------- const vector< SkillTreeEx >* SSkillTreeDB::GetSkillTreeData( int nSkillTree ) { auto pos = m_mapSkillTreeList.find( nSkillTree ); if( pos != m_mapSkillTreeList.end() ) { return pos->second; } return NULL; } //----------------------------------------------------------------------------------------------------------------- // 스킬 최대 레벨 얻기 //----------------------------------------------------------------------------------------------------------------- int SSkillTreeDB::GetSkillMaxLevel( int nSkillTree, int nSkillId ) { int Result = 0; const vector< SkillTreeEx >* skill_tree = GetSkillTreeData( nSkillTree ); if( skill_tree != NULL ) { auto pos = skill_tree->cbegin(); auto end = skill_tree->cend(); for( ; pos != end; ++pos ) { const SkillTreeEx& sk = (*pos); // 하나의 스킬 트리에서 같은 스킬이 여러개 나올수 있다. if( sk.skill_tree_id == nSkillTree && sk.skill_id == nSkillId && Result < sk.max_skill_lv ) { Result = sk.max_skill_lv; } } } return Result; } //----------------------------------------------------------------------------------------------------------------- // 인스턴스 얻기 //----------------------------------------------------------------------------------------------------------------- SSkillTreeDB & GetSkillTreeDB() { static SSkillTreeDB skilltreedb; return skilltreedb; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// SSkillStageDB::SSkillStageDB() { Init(); } SSkillStageDB::~SSkillStageDB() { Destroy(); } void SSkillStageDB::Init() { Load(); } void SSkillStageDB::Destroy() { _SKILL_FX* pSkillFx = NULL; bool res; res = m_hashSkillFx.get_first_value( pSkillFx ); while ( res ) { if ( pSkillFx != NULL ) { delete pSkillFx; } res = m_hashSkillFx.get_next_value( pSkillFx ); } m_hashSkillFx.clear(); } void SSkillStageDB::Load() { KStream * pRes = KFileManager::Instance().CreateStreamFromResource( "db_SkillStage.rdb" ); if( !pRes ) return; GAME_DB db_hdr; pRes->Read( &db_hdr, sizeof(db_hdr) ); //// RDB 와 Header의 사이즈 비교. //int fileSize = pRes->Size() - ( STR_DATE_BUFFER + sizeof( int ) ); //int headerSize = sizeof(_SKILL_FX) * db_hdr.nCount; //if( fileSize != headerSize ) //{ // char str[512] = { NULL, }; // sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ", // db_hdr.szDate, // __FILE__, // fileSize, // headerSize // ); // // ::MessageBox( g_hWnd, str, "Error", MB_OK ); // // if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES ) // { // exit( 1 ); // } //} for( int i(0); db_hdr.nCount>i; i++ ) { _SKILL_FX * pSkillFx = new _SKILL_FX; pRes->Read( pSkillFx, sizeof(_SKILL_FX) ); //마법류는 자동으로 설정 한다. if( pSkillFx->nCasting_Type_Id == 1 && pSkillFx->nStage_Type_Id != 1001 ) //임시(채광 채집 조작 스킬들은 DB모션을 사용한다 ) { int nCasting_Fx_Set_Id = pSkillFx->nCasting_Fx_Set_Id ; if( pSkillFx->szElemental == 0 ){ pSkillFx->nCasting_Start_Motion_Id = 70; pSkillFx->nCasting_Middle_Motion_Id = 80; pSkillFx->nCasting_Fx_Set_Id = 2002; } if( pSkillFx->szElemental == 1 ){ pSkillFx->nCasting_Start_Motion_Id = 71; pSkillFx->nCasting_Middle_Motion_Id = 81; pSkillFx->nCasting_Fx_Set_Id = 2003; } if( pSkillFx->szElemental == 2 ){ pSkillFx->nCasting_Start_Motion_Id = 72; pSkillFx->nCasting_Middle_Motion_Id = 82; pSkillFx->nCasting_Fx_Set_Id = 2004; } if( pSkillFx->szElemental == 3 ){ pSkillFx->nCasting_Start_Motion_Id = 73; pSkillFx->nCasting_Middle_Motion_Id = 83; pSkillFx->nCasting_Fx_Set_Id = 2005; } if( pSkillFx->szElemental == 4 ){ pSkillFx->nCasting_Start_Motion_Id = 74; pSkillFx->nCasting_Middle_Motion_Id = 84; pSkillFx->nCasting_Fx_Set_Id = 2006; } if( pSkillFx->szElemental == 5 ){ pSkillFx->nCasting_Start_Motion_Id = 75; pSkillFx->nCasting_Middle_Motion_Id = 85; pSkillFx->nCasting_Fx_Set_Id = 2007; } if( pSkillFx->szElemental == 6 ){ pSkillFx->nCasting_Start_Motion_Id = 76; pSkillFx->nCasting_Middle_Motion_Id = 86; pSkillFx->nCasting_Fx_Set_Id = 2008; } if( pSkillFx->szIs_Creature_Skill == 2 ) //몬스터 스킬일 경우 스킬연출 디비 FX값 참조 { pSkillFx->nCasting_Fx_Set_Id = nCasting_Fx_Set_Id; } //90 마법시전1 - 자기자신에 시전 //91 마법시전2 - 타인에 시전 (도움) //92 마법시전3 - 타인에 시전 (피해) //93 마법시전4 - 자기주변에 시전 //94 마법시전5 - 소환연출 //소환 스킬은 94번 모션 셋트임. if( pSkillFx->nStage_Type_Id == 1 || pSkillFx->nStage_Type_Id == 2 ) pSkillFx->nFire_Motion_Id = 94; if(pSkillFx->szHas_Target == 0 ) //셀프 스킬 pSkillFx->nFire_Motion_Id = 90; if( pSkillFx->szDeal_Damage == 0 ) //이로움 pSkillFx->nFire_Motion_Id = 91; else if( pSkillFx->szDeal_Damage == 1 ) //해로움 pSkillFx->nFire_Motion_Id = 92; pSkillFx->nFire_Motion_Id = 92; //FireMotionID는 스킬 발사 상황에 따라 달라 진다. SNewSkill 쪽에서 제어함. } _SKILL_FX * pFindSkill = NULL; if( m_hashSkillFx.lookup( pSkillFx->nID, pFindSkill ) == false ) { m_hashSkillFx.add( pSkillFx->nID, pSkillFx ); } else { _oprint( "!!!!Data Error SkillFx Code 가 중복되었습니다.!!!! %d\n", pSkillFx->nID ); // assert(0); //기획팀에 알려 주세여. 바로 수정 해야 합니다. delete pSkillFx; } } KFileManager::Instance().DeleteStream( pRes ); } _SKILL_FX* SSkillStageDB::GetSkillStageData( int nSkillID) { _SKILL_FX * pFindSkill = NULL; if( m_hashSkillFx.lookup( nSkillID, pFindSkill ) == false ) return NULL; else return pFindSkill; return NULL; } SSkillStageDB & GetSkillStageDB() { static SSkillStageDB SkillStageDB; return SkillStageDB; } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// SFieldTypeMaterialDB::SFieldTypeMaterialDB() { Init(); } SFieldTypeMaterialDB::~SFieldTypeMaterialDB() { Destroy(); } void SFieldTypeMaterialDB::Init() { Load(); } void SFieldTypeMaterialDB::Destroy() { _FIELD_TYPE_MATERIAL* pFieldTypeMaterial = NULL; bool res; res = m_hashFieldTypeMaterial.get_first_value( pFieldTypeMaterial ); while ( res ) { if ( pFieldTypeMaterial != NULL ) { delete pFieldTypeMaterial; } res = m_hashFieldTypeMaterial.get_next_value( pFieldTypeMaterial ); } m_hashFieldTypeMaterial.clear(); } void SFieldTypeMaterialDB::Load() { KStream * pRes = KFileManager::Instance().CreateStreamFromResource( "db_FieldTypeMaterial.rdb" ); if( !pRes ) return; GAME_DB db_hdr; pRes->Read( &db_hdr, sizeof(db_hdr) ); //// RDB 와 Header의 사이즈 비교. //int fileSize = pRes->Size() - ( STR_DATE_BUFFER + sizeof( int ) ); //int headerSize = sizeof(_FIELD_TYPE_MATERIAL) * db_hdr.nCount; // //if( fileSize != headerSize ) //{ // char str[512] = { NULL, }; // sprintf( str, "*** RDB Error !!! ***\n\n생성날짜%s\n파일:%s\n파일사이즈:%d\n헤더사이즈:%d\n ", // db_hdr.szDate, // __FILE__, // fileSize, // headerSize // ); // // ::MessageBox( g_hWnd, str, "Error", MB_OK ); // // if( ::MessageBox( g_hWnd, "RDB와 클라이언트가 맞지않습니다. 강제종료하시겠습니까?", "Error", MB_YESNO ) == IDYES ) // { // exit( 1 ); // } //} for( int i(0); db_hdr.nCount>i; i++ ) { _FIELD_TYPE_MATERIAL * pFieldTypeMaterial = new _FIELD_TYPE_MATERIAL; pRes->Read( pFieldTypeMaterial, sizeof(_FIELD_TYPE_MATERIAL) ); _FIELD_TYPE_MATERIAL * pFindSkill = NULL; if( m_hashFieldTypeMaterial.lookup( pFieldTypeMaterial->nMaterial, pFindSkill ) == false ) { m_hashFieldTypeMaterial.add( pFieldTypeMaterial->nMaterial, pFieldTypeMaterial ); } else { _oprint( "!!!!Data Error FieldTypeMaterial Code 가 중복되었습니다.!!!! %d\n", pFieldTypeMaterial->nMaterial ); // assert(0); //기획팀에 알려 주세여. 바로 수정 해야 합니다. delete pFieldTypeMaterial; } } KFileManager::Instance().DeleteStream( pRes ); } SFieldTypeMaterialDB & GetFieldTypeMaterialDB() { static SFieldTypeMaterialDB FiledTypeMaterialDB; return FiledTypeMaterialDB; } //----------------------------------------------------------------------------------------------------------------- // 분해 식 DB 인스턴스 얻기 //----------------------------------------------------------------------------------------------------------------- SSummonRandomSkillDB & GetSummonRandomSkillDB() { static SSummonRandomSkillDB SummonRandomSkillDB; return SummonRandomSkillDB; } //----------------------------------------------------------------------------------------------------------------- // 생성자 //----------------------------------------------------------------------------------------------------------------- SSummonRandomSkillDB::SSummonRandomSkillDB() { if( false == Load() ) { SDEBUGLOG( "[SSummonRandomSkillDB] Load Failed " ); assert( NULL ); } } //----------------------------------------------------------------------------------------------------------------- // 파괴자 //----------------------------------------------------------------------------------------------------------------- SSummonRandomSkillDB::~SSummonRandomSkillDB() { Destroy(); } //----------------------------------------------------------------------------------------------------------------- // RDB 파일 불러오기 //----------------------------------------------------------------------------------------------------------------- bool SSummonRandomSkillDB::Load() { KStream* pRes( KFileManager::Instance().CreateStreamFromResource( "db_SummonRandomSkill.rdb" ) ); if( NULL == pRes ) { SDEBUGLOG( "[SSummonRandomSkillDB] Create Stream Failed - [db_SummonRandomSkill.rdb]" ); assert( NULL ); return false; } GAME_DB db_hdr; string idKey; pRes->Read( &db_hdr, sizeof(db_hdr) ); for( int nCount = 0; nCount < db_hdr.nCount; nCount++ ) { SummonRandomSkillBase stSummonRandomSkillBase; size_t ReadSize( pRes->Read( &stSummonRandomSkillBase, sizeof(SummonRandomSkillBase) ) ); if( NULL == ReadSize ) { SDEBUGLOG( "[SSummonRandomSkillDB] Read Failed" ); assert( ReadSize ); return false; } PSUMMON_RANDOM_SKILL_ID pSummonRandomSkillID( new SUMMON_RANDOM_SKILL_ID() ); // 데이터 저장 용 if( NULL == pSummonRandomSkillID ) { SDEBUGLOG( "[SSummonRandomSkillDB] Alloc Failed" ); assert( pSummonRandomSkillID ); continue; } char szBuffer[256] = { NULL, }; set setSkillID; // 데이터 중복 검사 용 for( int nCount = 0; nCount < stSummonRandomSkillBase.skill_count; nCount++ ) { int nSkillID( stSummonRandomSkillBase.skill_id[nCount] ); if( NULL == nSkillID ) { #ifdef _DEV _sntprintf_s( szBuffer, _countof( szBuffer), _TRUNCATE, "[SSummonRandomSkillDB] Skill ID 가 0 입니다. 데이터를 무시합니다 : Group Unique ID - [%u], 스킬 아이디 [%u]번째", stSummonRandomSkillBase.skill_group_id, nCount ); MessageBox( HWND_DESKTOP, szBuffer, "[SSummonRandomSkillDB] 데이터 에러", MB_OK | MB_ICONERROR ); ZeroMemory( szBuffer, sizeof( szBuffer ) ); #endif continue; } if( false == ( setSkillID.insert( nSkillID ).second ) ) { #ifdef _DEV _sntprintf_s( szBuffer, _countof( szBuffer), _TRUNCATE, "[SSummonRandomSkillDB] Skill ID 중복 !! : Group Unique ID - [%u], 스킬 아이디 [%u]번째", stSummonRandomSkillBase.skill_group_id, nCount ); MessageBox( HWND_DESKTOP, szBuffer, "[SSummonRandomSkillDB] 데이터 에러", MB_OK | MB_ICONERROR ); ZeroMemory( szBuffer, sizeof( szBuffer ) ); #endif continue; } else pSummonRandomSkillID->vecSkillID.push_back( nSkillID ); } if( false == m_mapSummonRandomSkill.insert( pair( stSummonRandomSkillBase.skill_group_id, pSummonRandomSkillID ) ).second ) { SAFE_DELETE( pSummonRandomSkillID ); #ifdef _DEV _sntprintf_s( szBuffer, _countof( szBuffer), _TRUNCATE, "[SSummonRandomSkillDB] Gruop Unique ID 중복이거나 컨테이너 삽입에 실패하였습니다. : Group Unique ID - [%u]", stSummonRandomSkillBase.skill_group_id ); MessageBox( HWND_DESKTOP, szBuffer, "[SSummonRandomSkillDB] 데이터 에러", MB_OK | MB_ICONERROR ); ZeroMemory( szBuffer, sizeof( szBuffer ) ); #endif continue; } } KFileManager::Instance().DeleteStream( pRes ); return true; } //----------------------------------------------------------------------------------------------------------------- // 파괴 //----------------------------------------------------------------------------------------------------------------- void SSummonRandomSkillDB::Destroy() { for( SUMMON_RANDOM_SKILL_ITER Iter = m_mapSummonRandomSkill.begin(); Iter != m_mapSummonRandomSkill.end(); ++Iter ) { PSUMMON_RANDOM_SKILL_ID pSummonRandomSkillID( Iter->second ); SAFE_DELETE( pSummonRandomSkillID ); } m_mapSummonRandomSkill.clear(); } //----------------------------------------------------------------------------------------------------------------- // 랜덤 스킬 ID 리스트 얻기 //----------------------------------------------------------------------------------------------------------------- const SUMMON_RANDOM_SKILL_ID* const SSummonRandomSkillDB::GetRandomSkillIDList( const int nGroupID ) { SUMMON_RANDOM_SKILL_ITER Iter( m_mapSummonRandomSkill.find( nGroupID ) ); if( Iter != m_mapSummonRandomSkill.end() ) return Iter->second; return NULL; }