531 lines
16 KiB
C++
531 lines
16 KiB
C++
|
|
#pragma once
|
|
|
|
//#include <string>
|
|
#include <Windows.h>
|
|
#include "GameDefine.h"
|
|
#include "GameRule.h"
|
|
#include "ItemBase.h"
|
|
#include "DefaultModelRes.h"
|
|
#include "SkillBaseFile.h"
|
|
#include "Enc.h"
|
|
#include "SJobDB.h"
|
|
#include <dump/XException.h>
|
|
|
|
#include <toolkit/khash.h>
|
|
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
static const char * c_szNotFound = "NotFoundFile";
|
|
|
|
using std::string;
|
|
using std::vector;
|
|
|
|
namespace nsItemDB
|
|
{
|
|
struct ItemBaseEx_info_Client : public ItemBaseEx_info
|
|
{
|
|
ENC_INT real_uid;
|
|
};
|
|
|
|
// QA 테스트 시 아이템 아이디 확인을 위한 구조체 ( 개발 시 에만 쓰임 )
|
|
typedef struct stItemIdentityforDev
|
|
{
|
|
int m_uItemID;
|
|
string m_strItemName;
|
|
|
|
stItemIdentityforDev()
|
|
: m_strItemName( "" )
|
|
{
|
|
}
|
|
}ITEMIDENTITYFORDEV, *PITEMIDENTITYFORDEV;
|
|
};
|
|
|
|
using namespace nsItemDB;
|
|
using namespace GameRule;
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
/// Item reference DB
|
|
class SItemReferenceDB
|
|
{
|
|
private:
|
|
std::vector< char * > m_ItemReferenceList;
|
|
|
|
public:
|
|
SItemReferenceDB();
|
|
~SItemReferenceDB();
|
|
|
|
const char * GetReference( int nIndex );
|
|
void SetInfo( ItemBaseEx_info_Client * pBase, ItemBaseEx * nBase );
|
|
|
|
void Init();
|
|
void Destroy();
|
|
void Load();
|
|
|
|
public:
|
|
static SItemReferenceDB* m_pThis;
|
|
};
|
|
|
|
SItemReferenceDB & GetItemReferenceDB();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
/// Item DB
|
|
class SItemDB
|
|
{
|
|
public:
|
|
enum ITEM_ENHANCE_LEVEL
|
|
{
|
|
LEVEL_1 = 0,
|
|
LEVEL_2,
|
|
LEVEL_3,
|
|
LEVEL_MAX,
|
|
};
|
|
public:
|
|
SItemDB();
|
|
~SItemDB();
|
|
|
|
const std::vector< ItemEnhanceEffectBase >& Find(int nEnhanceID);
|
|
|
|
inline const ItemBaseEx_info * GetItemData( ENC_INT nItemID )
|
|
{
|
|
ItemBaseEx_info_Client * pFindItem = NULL;
|
|
if( m_hashItem.lookup( nItemID, pFindItem ) == false )
|
|
{
|
|
return (m_pDummyData);
|
|
}
|
|
else
|
|
{
|
|
return (pFindItem);
|
|
}
|
|
|
|
return (m_pDummyData);
|
|
}
|
|
|
|
// 해당 세트 아이템에 아이디와 일치하는 정보 가져오기
|
|
inline const std::vector<ItemBase*> GetSetItemData( int nSetItemID )
|
|
{
|
|
if( !m_vSetItemReturn.empty() )
|
|
m_vSetItemReturn.clear();
|
|
|
|
std::vector<ItemBase*>::iterator iter;
|
|
|
|
int i=0;
|
|
for( iter = m_vSetItem.begin(); iter != m_vSetItem.end(); ++iter )
|
|
{
|
|
if( m_vSetItem[i]->set_id == nSetItemID )
|
|
{
|
|
m_vSetItemReturn.push_back(*iter);
|
|
}
|
|
++i;
|
|
}
|
|
|
|
return m_vSetItemReturn;
|
|
|
|
}
|
|
|
|
inline short GetCoolTimeGroup( ENC_INT nItemID ) { return GetItemData( nItemID )->nCoolTimeGroup; }
|
|
inline int GetMaterial( ENC_INT nItemID ) { return GetItemData( nItemID )->nMaterial; }
|
|
inline int GetUseType( ENC_INT nItemID ) { return GetItemData( nItemID )->nType; }
|
|
inline int GetIconID( ENC_INT nItemID ) { return GetItemData( nItemID )->icon_id; }
|
|
inline const char * GetIconName( ENC_INT nItemID ) { return GetItemData( nItemID )->pIcon_name; }
|
|
inline bool IsJoin( ENC_INT nItemID ) { return GetItemData( nItemID )->CheckFlag( ItemBase::FLAG_JOIN ); }
|
|
inline bool IsJoin( ENC_INT nItemID, bool bSummon ) { return GetItemData( nItemID )->CheckFlag( ItemBase::FLAG_JOIN ) && !bSummon; } //added by gmpbigsun(20130318)
|
|
|
|
inline int GetPrice( ENC_INT nItemID ) { return GetItemData( nItemID )->nPrice; }
|
|
inline float GetWeight( ENC_INT nItemID ) { return GetItemData( nItemID )->fWeight; } //일단 int형으로
|
|
inline int GetGroup( ENC_INT nItemID ) { return GetItemData( nItemID )->nGroup; }
|
|
inline int GetRange( ENC_INT nItemID ) { return GetItemData( nItemID )->nRange; }
|
|
inline int GetTextID( ENC_INT nItemID ) { return GetItemData( nItemID )->nNameId; }
|
|
inline int GetToolTipID( ENC_INT nItemID ) { return GetItemData( nItemID )->nToolTipID; }
|
|
inline int GetSkillID( ENC_INT nItemID ) { return GetItemData( nItemID )->nSkillID; }
|
|
|
|
inline ItemBase::ItemWearType GetWearType( ENC_INT nItemID ) { return GetItemData( nItemID )->WearType; }
|
|
inline ItemBase::ItemClass GetClassID( ENC_INT nItemID ) { return GetItemData( nItemID )->nClass; }
|
|
inline int GetItemRank( ENC_INT nItemID ) { return GetItemData( nItemID )->nRank; }
|
|
|
|
inline const char* GetDem( ENC_INT nItemID, int nEnhanceLevel )
|
|
{
|
|
ITEM_ENHANCE_LEVEL nLevel = CheckItemLevel(nEnhanceLevel);
|
|
|
|
if( nLevel == LEVEL_1 ) return GetItemData( nItemID )->pModel00;
|
|
else if( nLevel == LEVEL_2 ) return GetItemData( nItemID )->pModel01;
|
|
else if( nLevel == LEVEL_3 ) return GetItemData( nItemID )->pModel02;
|
|
|
|
_oprint( "Item ID : %d, Item Level %d\n", nItemID, nEnhanceLevel );
|
|
assert( false && "SItemDB::GetDem FAILED" );
|
|
return "";
|
|
}
|
|
inline const char* GetDef( ENC_INT nItemID, int nEnhanceLevel )
|
|
{
|
|
ITEM_ENHANCE_LEVEL nLevel = CheckItemLevel(nEnhanceLevel);
|
|
|
|
if( nLevel == LEVEL_1 ) return GetItemData( nItemID )->pModel03;
|
|
else if( nLevel == LEVEL_2 ) return GetItemData( nItemID )->pModel04;
|
|
else if( nLevel == LEVEL_3 ) return GetItemData( nItemID )->pModel05;
|
|
|
|
_oprint( "Item ID : %d, Item Level %d\n", nItemID, nEnhanceLevel );
|
|
assert( false && "SItemDB::GetDef FAILED" );
|
|
return "";
|
|
}
|
|
inline const char* GetAsm( ENC_INT nItemID, int nEnhanceLevel )
|
|
{
|
|
ITEM_ENHANCE_LEVEL nLevel = CheckItemLevel(nEnhanceLevel);
|
|
|
|
if( nLevel == LEVEL_1 ) return GetItemData( nItemID )->pModel06;
|
|
else if( nLevel == LEVEL_2 ) return GetItemData( nItemID )->pModel07;
|
|
else if( nLevel == LEVEL_3 ) return GetItemData( nItemID )->pModel08;
|
|
|
|
_oprint( "Item ID : %d, Item Level %d\n", nItemID, nEnhanceLevel );
|
|
assert( false && "SItemDB::GetAsm FAILED" );
|
|
return "";
|
|
}
|
|
inline const char* GetAsf( ENC_INT nItemID, int nEnhanceLevel )
|
|
{
|
|
ITEM_ENHANCE_LEVEL nLevel = CheckItemLevel(nEnhanceLevel);
|
|
|
|
if( nLevel == LEVEL_1 ) return GetItemData( nItemID )->pModel09;
|
|
else if( nLevel == LEVEL_2 ) return GetItemData( nItemID )->pModel10;
|
|
else if( nLevel == LEVEL_3 ) return GetItemData( nItemID )->pModel11;
|
|
|
|
_oprint( "Item ID : %d, Item Level %d\n", nItemID, nEnhanceLevel );
|
|
assert( false && "SItemDB::GetAsf FAILED" );
|
|
return "";
|
|
}
|
|
inline const char* GetGam( ENC_INT nItemID, int nEnhanceLevel )
|
|
{
|
|
ITEM_ENHANCE_LEVEL nLevel = CheckItemLevel(nEnhanceLevel);
|
|
|
|
if( nLevel == LEVEL_1 ) return GetItemData( nItemID )->pModel12;
|
|
else if( nLevel == LEVEL_2 ) return GetItemData( nItemID )->pModel13;
|
|
else if( nLevel == LEVEL_3 ) return GetItemData( nItemID )->pModel14;
|
|
|
|
_oprint( "Item ID : %d, Item Level %d\n", nItemID, nEnhanceLevel );
|
|
assert( false && "SItemDB::GetGam FAILED" );
|
|
return "";
|
|
}
|
|
inline const char* GetGaf( ENC_INT nItemID, int nEnhanceLevel )
|
|
{
|
|
ITEM_ENHANCE_LEVEL nLevel = CheckItemLevel(nEnhanceLevel);
|
|
|
|
if( nLevel == LEVEL_1 ) return GetItemData( nItemID )->pModel15;
|
|
else if( nLevel == LEVEL_2 ) return GetItemData( nItemID )->pModel16;
|
|
else if( nLevel == LEVEL_3 ) return GetItemData( nItemID )->pModel17;
|
|
|
|
_oprint( "Item ID : %d, Item Level %d\n", nItemID, nEnhanceLevel );
|
|
assert( false && "SItemDB::GetGaf FAILED" );
|
|
return "";
|
|
}
|
|
inline const char* GetDropFileName( ENC_INT nItemID )
|
|
{
|
|
return GetItemData( nItemID )->pDrop_model;
|
|
}
|
|
|
|
|
|
inline bool GetBaseVar( ENC_INT nItemID, int nIndex, int& rGetType, double& rGetVar1, double& rGetVar2 )
|
|
{
|
|
if( 0 <= nIndex && nIndex < ItemBase::MAX_OPTION_NUMBER )
|
|
{
|
|
const ItemBaseEx_info * pItem = GetItemData( nItemID );
|
|
|
|
rGetType = pItem->nBaseType[ nIndex ];
|
|
rGetVar1 = pItem->dBaseVar1[ nIndex ];
|
|
rGetVar2 = pItem->dBaseVar2[ nIndex ];
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
inline bool GetOptionVar( ENC_INT nItemID, int nIndex, int& rGetType, double& rGetVar1, double& rGetVar2 )
|
|
{
|
|
if( 0 <= nIndex && nIndex < ItemBase::MAX_OPTION_NUMBER )
|
|
{
|
|
const ItemBaseEx_info * pItem = GetItemData( nItemID );
|
|
|
|
rGetType = pItem->nOptType[ nIndex ];
|
|
rGetVar1 = pItem->dOptVar1[ nIndex ];
|
|
rGetVar2 = pItem->dOptVar2[ nIndex ];
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// 장착 가능한 종족인가?
|
|
inline bool IsWearablebyRace( ENC_INT nItemID, int nRace )
|
|
{
|
|
const ItemBaseEx_info* pItem = GetItemData( nItemID );
|
|
return IsWearablebyRace( pItem, nRace );
|
|
}
|
|
inline bool IsWearablebyRace( const ItemBaseEx_info* pItem, int nRace )
|
|
{
|
|
switch( nRace )
|
|
{
|
|
case GCLAN_DEVA : return (0 != (pItem->nLimit & ItemBase::LIMIT_DEVA ));
|
|
case GCLAN_ASURA: return (0 != (pItem->nLimit & ItemBase::LIMIT_ASURA));
|
|
case GCLAN_GAIA : return (0 != (pItem->nLimit & ItemBase::LIMIT_GAIA ));
|
|
default: return false;
|
|
}
|
|
}
|
|
|
|
/// 장착 가능한 직업인가?
|
|
inline bool IsWearablebyJob( ENC_INT nItemID, int nJobID, int nRace )
|
|
{
|
|
const ItemBaseEx_info* pItem = GetItemData( nItemID );
|
|
return IsWearablebyJob( pItem, nJobID, nRace );
|
|
}
|
|
inline bool IsWearablebyJob( const ItemBaseEx_info* pItem, int nJobID, int nRace )
|
|
{
|
|
if( pItem->nLimit & ItemBase::LIMIT_HUNTER && SJobDB::IsHunter( nJobID, nRace ) ) return true;
|
|
if( pItem->nLimit & ItemBase::LIMIT_FIGHTER && SJobDB::IsFighter( nJobID, nRace ) ) return true;
|
|
if( pItem->nLimit & ItemBase::LIMIT_MAGICIAN && SJobDB::IsMagician( nJobID, nRace ) ) return true;
|
|
if( pItem->nLimit & ItemBase::LIMIT_SUMMONER && SJobDB::IsSummoner( nJobID, nRace ) ) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/// 장착 가능한 전직인가?
|
|
inline bool IsWearablebyJobDepth( ENC_INT nItemID, int nJobID )
|
|
{
|
|
const ItemBaseEx_info* pItem = GetItemData( nItemID );
|
|
return IsWearablebyJobDepth( pItem, nJobID );
|
|
}
|
|
inline bool IsWearablebyJobDepth( const ItemBaseEx_info* pItem, int nJobID )
|
|
{
|
|
const JobInfoEx* pJobInfo = GetJobDB().GetJobData( nJobID );
|
|
if( pJobInfo )
|
|
{
|
|
if( ( 1 << pJobInfo->job_depth & pItem->job_depth ) == 0 )
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// 장착 가능한 레벨인가?
|
|
inline bool IsWearablebyLevel( ENC_INT nItemID, int nLevel )
|
|
{
|
|
const ItemBaseEx_info* pItem = GetItemData( nItemID );
|
|
return IsWearablebyLevel( pItem, nLevel );
|
|
}
|
|
inline bool IsWearablebyLevel( const ItemBaseEx_info* pItem, int nLevel )
|
|
{
|
|
// 최소 레벨 체크
|
|
int nLevelLimit = 1;
|
|
if ( 0 < pItem->nMinLevel ) // 아이템 랭크와 상관없이 설정된 레벨에 따라서 표시
|
|
nLevelLimit = pItem->nMinLevel;
|
|
else
|
|
nLevelLimit = GameRule::GetItemLevelLimit( pItem->nRank );
|
|
|
|
if( nLevelLimit < 1 )
|
|
nLevelLimit = 1;
|
|
|
|
if( nLevelLimit > nLevel )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 최대 레벨 체크
|
|
if ( 0 < pItem->nMaxLevel )
|
|
{
|
|
if( nLevel > pItem->nMaxLevel )
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
inline const char * GetFileName( int nRace, int nSex, ENC_INT nItemID, int nEnhanceLevel )
|
|
{
|
|
if( nRace == GCLAN_GAIA && nSex == SEX_FEMALE ) return GetGaf( nItemID, nEnhanceLevel );
|
|
else if( nRace == GCLAN_GAIA && nSex == SEX_MALE ) return GetGam( nItemID, nEnhanceLevel );
|
|
else if( nRace == GCLAN_DEVA && nSex == SEX_FEMALE ) return GetDef( nItemID, nEnhanceLevel );
|
|
else if( nRace == GCLAN_DEVA && nSex == SEX_MALE ) return GetDem( nItemID, nEnhanceLevel );
|
|
else if( nRace == GCLAN_ASURA && nSex == SEX_FEMALE ) return GetAsf( nItemID, nEnhanceLevel );
|
|
else if( nRace == GCLAN_ASURA && nSex == SEX_MALE ) return GetAsm( nItemID, nEnhanceLevel );
|
|
|
|
return c_szNotFound;
|
|
}
|
|
|
|
inline bool GetDecoModelChange( ENC_INT nItemID )
|
|
{
|
|
const ItemBaseEx_info * pItem = GetItemData( nItemID );
|
|
if( pItem ) return pItem->deco_model_change;
|
|
|
|
return false;
|
|
}
|
|
|
|
inline const char* GetAdditionalTexture(ENC_INT nItemID)
|
|
{
|
|
return GetItemData( nItemID )->pTexture_filename;
|
|
}
|
|
|
|
|
|
ITEM_ENHANCE_LEVEL CheckItemLevel( int nItemLevel );
|
|
vector<ITEMIDENTITYFORDEV> GetItemIdentityList( string strFindItemName );
|
|
|
|
static bool IsWearable( ENC_INT nItemID, int nJobID, int nRace, int nLevel );
|
|
static bool IsWearable( const ItemBaseEx_info* pItem, int nJobID, int nRace, int nLevel );
|
|
|
|
|
|
protected:
|
|
|
|
void Init();
|
|
void Destroy();
|
|
|
|
void Load();
|
|
|
|
struct hashPr_mod_ENC_INT
|
|
{
|
|
typedef ENC_INT Key;
|
|
static inline unsigned getindex( const Key& key, int nCapacity ) { return unsigned( key.hash_id() ) % nCapacity; }
|
|
static inline bool isequal( const Key& key1, const Key& key2 ) { return key1 == key2; }
|
|
static inline bool isless( const Key& key1, const Key& key2 ) { return key1.prior( key2 ); }
|
|
};
|
|
|
|
|
|
KHash< struct ItemBaseEx_info_Client*, hashPr_mod_ENC_INT> m_hashItem;
|
|
std::map< int, std::vector< ItemEnhanceEffectBase > > m_mapEnhanceEffect;
|
|
std::vector<ItemBase*> m_vSetItem;
|
|
std::vector<ItemBase*> m_vSetItemReturn;
|
|
|
|
private:
|
|
ItemBaseEx_info_Client* m_pDummyData;
|
|
|
|
public:
|
|
static SItemDB* m_pThis;
|
|
};
|
|
|
|
SItemDB & GetItemDB();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
/// 기본 보여주는 메쉬~
|
|
class SFaceWinkDB
|
|
{
|
|
private:
|
|
|
|
struct FaceWinkData
|
|
{
|
|
int model_id;
|
|
|
|
std::string deva_male;
|
|
std::string deva_female;
|
|
std::string asura_male;
|
|
std::string asura_female;
|
|
std::string gaia_male;
|
|
std::string gaia_female;
|
|
};
|
|
|
|
KHash< FaceWinkData*, hashPr_mod_int> m_hashFaceWinkRes;
|
|
|
|
public:
|
|
SFaceWinkDB();
|
|
~SFaceWinkDB();
|
|
|
|
const char* GetFileName( int nRace, int nSex, int nDefaultID );
|
|
|
|
void Init();
|
|
void Destroy();
|
|
void Load();
|
|
};
|
|
|
|
SFaceWinkDB & GetFaceWinkDB();
|
|
|
|
class SDefaultItemDB
|
|
{
|
|
private:
|
|
KHash< DefaultModelResforGame*, hashPr_mod_int> m_hashDefaultModelRes;
|
|
public:
|
|
void Init();
|
|
void Destroy();
|
|
void Load();
|
|
|
|
//기본
|
|
int GetHairID( int nIndex );
|
|
int GetFaceID( int nIndex );
|
|
int GetBodyID( int nIndex );
|
|
int GetHandID( int nIndex );
|
|
int GetFootID( int nIndex );
|
|
int GetInnerID( int nIndex );
|
|
|
|
int GetDecoFaceGroupID( int nID );
|
|
int GetDecoHairGroupID( int nID );
|
|
|
|
int GetFaceGroupID( int nIndex );
|
|
int GetHairGroupID( int nIndex );
|
|
int GetBodyGroupID( int nIndex );
|
|
|
|
//고급
|
|
int GetTopBodyID( int nIndex );
|
|
int GetTopHandID( int nIndex );
|
|
int GetTopFootID( int nIndex );
|
|
|
|
//기본
|
|
int GetHairIndex( int nID );
|
|
int GetFaceIndex( int nID );
|
|
int GetBodyIndex( int nID );
|
|
int GetHandIndex( int nID );
|
|
int GetFootIndex( int nID );
|
|
int GetInnerIndex( int nID );
|
|
|
|
//고급
|
|
int GetTopBodyIndex( int nID );
|
|
int GetTopHandIndex( int nID );
|
|
int GetTopFootIndex( int nID );
|
|
|
|
//기본
|
|
unsigned int GetHairCount() { return (unsigned int)m_HairItemList.size(); }
|
|
unsigned int GetFaceCount() { return (unsigned int)m_FaceItemList.size(); }
|
|
unsigned int GetBodyCount() { return (unsigned int)m_BodyItemList.size(); }
|
|
unsigned int GetHandCount() { return (unsigned int)m_HandItemList.size(); }
|
|
unsigned int GetFootCount() { return (unsigned int)m_FootItemList.size(); }
|
|
|
|
//고급
|
|
unsigned int GetTopBodyCount() { return (unsigned int)m_TopRank_BodyItemList.size(); }
|
|
unsigned int GetTopHandCount() { return (unsigned int)m_TopRank_HandItemList.size(); }
|
|
unsigned int GetTopFootCount() { return (unsigned int)m_TopRank_FootItemList.size(); }
|
|
|
|
const char* GetFileName( int nRace, int nSex, int nDefaultID );
|
|
|
|
void SetCurFaceIndex( int nIndex ) { m_nCurFaceIndex = nIndex; }
|
|
int GetCurFaceIndex() { return m_nCurFaceIndex; }
|
|
|
|
enum _DEF_ITEM
|
|
{
|
|
DEF_ITEM_ARMOR = 2, ///< 의상
|
|
DEF_ITEM_GLOVE = 5, ///< 장갑
|
|
DEF_ITEM_FOOTS = 6, ///< 부츠
|
|
DEF_ITEM_HAIR = 14, ///< 헤어
|
|
DEF_ITEM_FACE = 15, // Face
|
|
DEF_ITEM_INNER = 16, ///< 속옷
|
|
};
|
|
|
|
enum _RANK_ITEM
|
|
{
|
|
DEF_RANK = 1, ///< 기본
|
|
TOP_RANK = 2, ///< 고급
|
|
};
|
|
public:
|
|
SDefaultItemDB();
|
|
~SDefaultItemDB();
|
|
|
|
std::vector< DefaultModelResforGame* > m_HairItemList;
|
|
std::vector< DefaultModelResforGame* > m_FaceItemList;
|
|
std::vector< DefaultModelResforGame* > m_BodyItemList;
|
|
std::vector< DefaultModelResforGame* > m_HandItemList;
|
|
std::vector< DefaultModelResforGame* > m_FootItemList;
|
|
std::vector< DefaultModelResforGame* > m_InnerItemList;
|
|
|
|
std::vector< DefaultModelResforGame* > m_TopRank_BodyItemList;
|
|
std::vector< DefaultModelResforGame* > m_TopRank_HandItemList;
|
|
std::vector< DefaultModelResforGame* > m_TopRank_FootItemList;
|
|
|
|
int m_nCurFaceIndex;
|
|
|
|
};
|
|
|
|
SDefaultItemDB & GetDefaultItemDB();
|