#include "ObjectDataClass.h"
#include "TestDataClass.h"
#include "MyBaseInc.h"
#include <fstream>
#pragma warning (disable:4949)
#pragma unmanaged

ObjectDataClass*    g_ObjectData = NULL;
//----------------------------------------------------------------------------------------------------
ObjectDataClass::ObjectDataClass( const char* InitPath )
{
    char* LoadFile[] = {  "WeaponObject.DB" , "ArmorObject.DB" , "ItemObject.DB" , "NPCObject.DB" , "MagicObject.DB" 
        , "AddPowerObject.DB", "QuestDetailObject.DB" , "RuneObject.DB" , "FlagObject.DB" , "RecipeObject.DB"
        , "ImageObject.DB","QuestNPCObject.DB", "KeyItemObject.DB", "LearnMagic.DB" , "ShopObject.DB" , "SuitObject.DB" 
		, "CampObject.DB" ,"TreasureObject.DB" ,"MagicCollectObject.DB" , "PlayerObject.DB" , NULL } ;

    bool    Ret , OKFlag = true;
    int     i , j;
	char	Buf[4096];

    for( i = 0 ; LoadFile[i] != NULL ; i++ )
    {
        
        Ret = _ObjectDB.OpenFile(  CombineFilePath( InitPath , LoadFile[i] ) );
        if( Ret == false)
		{            
			sprintf( Buf , "File = %s" , CombineFilePath( InitPath , LoadFile[i] ) );
			MessageBox( NULL , Buf , "LoadFile 初始化失敗!!" ,MB_OK );
			OKFlag = false;
        }
    }

    //載入測試資料
    NS_TestData::Init( &_ObjectDB );

    //-------------------------------------------------------------------------------------------------------

    char * LoadTable[] = { "FixTable.Db" , "RaceTable.DB" , "SexTable.DB" , "VocTable.DB" , "ExpTable.DB" , "SkillBaseTable.DB" 
						, "JobSkill.DB" , "JobEqSkillTable.DB" , "WeaponArgTable.DB", "ArmorArgTable.DB" 
						, "BaseMagicList.DB" , "ResistArgTable.DB" , "RefineExpTable.DB" , NULL  };
    ObjectDataFileClass<LoadTableStruct> ObjectTB;
    for( i = 0 ; LoadTable[i] != NULL ; i++ )
    {
        
        Ret = ObjectTB.OpenFile( CombineFilePath( InitPath , LoadTable[i] ) );
        if( Ret == false)
        {
			sprintf( Buf , "File = %s" , CombineFilePath( InitPath , LoadTable[i] ) );
            MessageBox( NULL , Buf , "LoadTable 初始化失敗!!" ,MB_OK );
            OKFlag = false;
        }
    }

    //載入Table表
    //    char* TempPoint;
    LoadTableStruct*  TempTable;
    for( i = 0 ; i < _MAX_RACE_COUNT_ ; i++ )
    {
        TempTable = ObjectTB.GetObj( i + Def_ObjectClass_Table );

        if( TempTable == NULL )
            break;

        RoleValueData::RaceArg[i] = TempTable->ArgTB;
    }

    for( i = 0 ; i < _MAX_VOCATION_COUNT_ ; i++ )
    {
        TempTable = ObjectTB.GetObj( i + Def_ObjectClass_Table + 1000 );

        if( TempTable == NULL )
            break;

        RoleValueData::VocArg[i] = TempTable->ArgTB;
    }

    for( i = 0 ; i < _MAX_SEX_COUNT_ ; i++ )
    {
        TempTable = ObjectTB.GetObj( i + Def_ObjectClass_Table + 2000 );

        if( TempTable == NULL )
            break;

        RoleValueData::SexArg[i] = TempTable->ArgTB;
    }


    TempTable = ObjectTB.GetObj(  Def_ObjectClass_Table + 3000 );

    if( TempTable != NULL )
    {
        RoleValueData::FixArg = TempTable->FixTB;
    }


    for( i = 0 ; i < _MAX_LEVEL_ ; i++ )
    {
        TempTable = ObjectTB.GetObj( i + Def_ObjectClass_Table + 5000 );

        if( TempTable == NULL )
            break;

        memcpy( RoleValueData::SkillValueBase[i] , TempTable->SkillValueBase , sizeof(RoleValueData::SkillValueBase[i])  );
    }

    for( i = 0 ; i < _MAX_SKILLVALUE_TYPE ; i++ )
    {
        TempTable = ObjectTB.GetObj( i + Def_ObjectClass_Table + 6000 );

        if( TempTable == NULL )
            break;

        memcpy( RoleValueData::JobSkillValue[i] , TempTable->JobSkillValue , sizeof(RoleValueData::JobSkillValue[i])  );
//		RoleValueData::WeaponBaseDelayTime[ i ] = TempTable->DelayTime;
	}

	TempTable = ObjectTB.GetObj(  Def_ObjectClass_Table + 7000 );

	if( TempTable != NULL )
	{
		for( i = 0 ; i < _MAX_VOCATION_COUNT_ ; i++  )
			RoleValueData::JobWearSkill[i]._Skill = TempTable->JobWearSkill[i]._Skill;
	}


	TempTable = ObjectTB.GetObj(  Def_ObjectClass_Table + 8000 );

	if( TempTable != NULL )
	{
		for( i = 0 ; i < _MAX_SKILLVALUE_TYPE ; i++  )
		{
			RoleValueData::WeaponBaseDelayTime[ i ] = TempTable->WeaponBaseDelayTime[ i ];
			RoleValueData::WeaponBaseDmg[ i ] = TempTable->WeaponBaseDmg[ i ];
		}
	}
//	裝備比例資料
//	TempTable = ObjectTB.GetObj(  Def_ObjectClass_Table + 9000 );

	
	//基本法術列表
	TempTable = ObjectTB.GetObj(  Def_ObjectClass_Table + 10000 );

	if( TempTable != NULL )
	{
		memcpy( RoleDataEx::BaseMagicList , TempTable->BaseMagicList , sizeof(RoleDataEx::BaseMagicList) );
	}

	//抗性表
	vector<ResistArgumentStruct> ResistArgList;
	for( i = 0 ; i < 1000 ; i++  )
	{
		TempTable = ObjectTB.GetObj(  Def_ObjectClass_Table + 11000 + i );
		if( TempTable == NULL )
			break;
		ResistArgList.push_back( TempTable->ResistArg );
	}
	//抗性值計算
	RoleValueData::ResistArgList.clear();
	ResistArgumentStruct HiResistArg;
	ResistArgumentStruct LowResistArg;
	ResistArgumentStruct MidResistArg;
	for( j = 1 ; j < (int)ResistArgList.size() ; j++ )
	{
		HiResistArg = ResistArgList[j];
		LowResistArg = ResistArgList[j-1];
			
		for( i = LowResistArg.Resist ; i < HiResistArg.Resist ; i++ )
		{
			for( int k = 0 ; k < 5 ; k++ )
			{
				float Rate = float( HiResistArg.PowerList[k] - LowResistArg.PowerList[k] ) / (  HiResistArg.Resist - LowResistArg.Resist );

				MidResistArg.Resist = i;
				MidResistArg.PowerList[k] =  int( ( i - LowResistArg.Resist ) * Rate + LowResistArg.PowerList[k] );
			}
			for( int k = 1 ; k < 4 ; k++ )
			{
				MidResistArg.PowerList[k] += MidResistArg.PowerList[k-1];
			}
			MidResistArg.Power100 = 100;
			RoleValueData::ResistArgList.push_back( MidResistArg );
		}	
	}
	RoleValueData::ResistArgList.push_back( HiResistArg );


	//煉製的經驗值表
	TempTable = ObjectTB.GetObj(  Def_ObjectClass_Table + 12000 );

	if( TempTable != NULL )
	{
		memcpy( RoleDataEx::RefineExpTable , TempTable->RefineExp , sizeof(RoleDataEx::RefineExpTable) );
	}
    //-------------------------------------------------------------------------------------------------------
    RoleValueData::CalBaseTB( );
    //-------------------------------------------------------------------------------------------------------
    //載入 Exp表 
    //-------------------------------------------------------------------------------------------------------
    //GUID = Def_ObjectClass_Table + 400;
    for( i = 0 ; i < _MAX_LEVEL_ ; i ++ )
    {
        TempTable = ObjectTB.GetObj(  Def_ObjectClass_Table + 4001 + i );

        if( TempTable == NULL )
        {
			if( i < 100 )
				MessageBox( NULL , "載入Exp錯誤" , "Error" , MB_OK );
            break;
        }
        memcpy( RoleDataEx::RoleExp[i] , TempTable->ExpTB , sizeof(RoleDataEx::RoleExp[i])  );
    }
	//設定SkillValueExp
	for( i = 0 ; i < _MAX_LEVEL_ ; i ++ )
	{
		RoleDataEx::SkillValueExp[i] = RoleValueData::FixArg.JobExSkillExp*(float)RoleDataEx::RoleExp[i][0]/100;
	}

	//-------------------------------------------------------------------------------------------------------
	//讀取頻道字串
	//-------------------------------------------------------------------------------------------------------
	
	char* FileName;

	{
		fstream file1;

		FileName = CombineFilePath( InitPath , "ZoneChannel.DB" );	
		file1.open( FileName , ios::in );	
		if( file1.is_open() == false )
		{
			MessageBox( NULL ,  "ZoneChannel 開檔失敗" , "警告" , MB_OK );
			return;
		}

		while( !file1.eof() )
		{   
			file1.getline( Buf , sizeof( Buf ) );
			if( strlen( Buf ) != 0 )
				RoleDataEx::ZoneChannel.push_back( Buf );
		}

		file1.close();

	}
	//-------------------------------------------------------------------------------------------------------
	// 讀取字串表
	//-------------------------------------------------------------------------------------------------------
	{
		fstream file1;
		FileName = CombineFilePath( InitPath , "String.DB" );	
		file1.open( FileName , ios::in | ios::binary );	

		if( file1.is_open() == false )
		{
			MessageBox( NULL ,  "String 開檔失敗" , "警告" , MB_OK );
			return;
		}

		StaticString<_MAX_LUA_FUNTIONNAMESIZE_> KeyStr;		
		int		ContentSize;
		StaticString<2048> Content;	
		
		while( !file1.eof()  )
		{   
			file1.read( (char*)KeyStr.Begin() , sizeof( KeyStr ) );
			file1.read( (char*)&ContentSize , sizeof( ContentSize ) );
			file1.read( (char*)Content.Begin() , ContentSize );

			_StringMap[ KeyStr.Begin() ] = Content.Begin();

		}
		file1.close();
	}
	//-------------------------------------------------------------------------------------------------------
	SetStringLink();

    SetImageObjLink();
    SetMagicLink( );
	SetEqAttributeLink();
	SetQuestLink();
	SetRecipeLink();

}
ObjectDataClass::~ObjectDataClass( )
{

}
//----------------------------------------------------------------------------------------------------
GameObjDbStructEx*    ObjectDataClass::GetObj( int ObjID )
{
    return _ObjectDB.GetObj( ObjID );
}

//----------------------------------------------------------------------------------------------------
bool    ObjectDataClass::Init( const char* InitPath )
{
    if( g_ObjectData != NULL )
    {
        delete g_ObjectData;
        g_ObjectData = NULL;
    }

    g_ObjectData = new ObjectDataClass( InitPath );

    return true;
}
//----------------------------------------------------------------------------------------------------
bool    ObjectDataClass::Release( )
{
    if( g_ObjectData == NULL )
        return false;

    delete g_ObjectData;
    g_ObjectData = NULL;

    return true;
}
//----------------------------------------------------------------------------------------------------
//物件資料
ObjectDataFileClass<GameObjDbStructEx>*	ObjectDataClass::ObjectDB()
{
    return &_ObjectDB;
}
//----------------------------------------------------------------------------------------------------
void ObjectDataClass::SetImageObjLink( )
{
    static GameObjDbStruct	EmptyImageObj;
    GameObjDbStruct	*Obj;
    GameObjDbStruct	*ImageObj;

    memset( &EmptyImageObj , 0 , sizeof(EmptyImageObj) );

    _ObjectDB.GetDataByOrder( true );

    for( int i = 0 ; i < _ObjectDB.TotalInfoCount() ; i++ )
    {
        Obj = _ObjectDB.GetDataByOrder();

        ImageObj = (GameObjDbStruct*)_ObjectDB.GetObj( Obj->ImageID );
        if( ImageObj == NULL )
            Obj->ImageObj = &EmptyImageObj.Image;
        else
            Obj->ImageObj = &ImageObj->Image;
    }
}
//----------------------------------------------------------------------------------------------------
void ObjectDataClass::SetMagicLink( )
{
    GameObjDbStructEx	*Obj;
    GameObjDbStructEx	*BaseMagicObj;

    _ObjectDB.GetDataByOrder( true );

    for( int i = 0 ; i < _ObjectDB.TotalInfoCount() ; i++ )
    {
        Obj = _ObjectDB.GetDataByOrder();

        if( !Obj->IsMagicCollect() )
            continue;
        memset( Obj->AllMagicCol , 0 , sizeof(Obj->AllMagicCol) );
        Obj->MaxMagicColCount = 0;
		if( Obj->MagicCol.MagicLV == 0 )
		{
			Obj->MagicCol.MagicLV = 1; 
			Obj->MagicCol.MagicBase = Obj->GUID;
		}
			
    }


    _ObjectDB.GetDataByOrder( true );
    for( int i = 0 ; i < _ObjectDB.TotalInfoCount() ; i++ )
    {
        Obj = _ObjectDB.GetDataByOrder();
        
        if( !Obj->IsMagicCollect() )
            continue;

        //如果為一級的法術一定要是本身
        if ( Obj->MagicCol.MagicLV == 1 && Obj->GUID != Obj->MagicCol.MagicBase  )
        {
            Print( LV5 , "SetMagicLink" , "有問題 MagicID = %d MagicLV = 1  MagicBase = %d" , Obj->GUID , Obj->MagicCol.MagicBase );
            continue;
        }

        BaseMagicObj = _ObjectDB.GetObj( Obj->MagicCol.MagicBase );

        if( BaseMagicObj == NULL )
        {
            Print( LV5 , "SetMagicLink" , "有問題 MagicID = %d MagicBase=%d找不到" , Obj->GUID , Obj->MagicCol.MagicBase );
            continue;
        }
        if( Obj->MagicCol.MagicLV >= 10 || Obj->MagicCol.MagicLV <= 0 )
        {
            Print( LV5 , "SetMagicLink" , "有問題 MagicID = %d MagicLV=%d " , Obj->GUID , Obj->MagicCol.MagicLV );
            continue;
        }

		if( BaseMagicObj != Obj )
		{
			BaseMagicObj->AllMagicCol[ Obj->MagicCol.MagicLV - 1 ] = Obj;
		}
		else
			BaseMagicObj->AllMagicCol[ 0 ] = Obj;

		if( Obj->MagicCol.MagicLV > BaseMagicObj->MaxMagicColCount )
		{
			BaseMagicObj->MaxMagicColCount = Obj->MagicCol.MagicLV;
		}

    }

    //資料檢查
    _ObjectDB.GetDataByOrder( true );
    for( int i = 0 ; i < _ObjectDB.TotalInfoCount() ; i++ )
    {
        Obj = _ObjectDB.GetDataByOrder();

        if( !Obj->IsMagicCollect() )
            continue;
        
		for( int i = 0 ; i < _MAX_MAGICCOLLECT_COUNT_ ; i++ )
		{
			Obj->MagicCol.Magic[i].MagicBaseDB = _ObjectDB.GetObj( Obj->MagicCol.Magic[i].MagicBaseID );
		}

        if( Obj->AllMagicCol[0] != Obj )
            continue;

        for( int j = 1 ; j < Obj->MaxMagicColCount ; j++ )
        {
            if( Obj->AllMagicCol[j] == NULL )
            {
                Print( LV5 , "SetMagicLink" , "系列的法術有缺 BaseMagicID = %d , 缺的LV= %d ", Obj->GUID , j );
                continue;
            }
            memcpy( Obj->AllMagicCol[j]->AllMagicCol , Obj->AllMagicCol , sizeof(Obj->AllMagicCol) );
            Obj->AllMagicCol[j]->MaxMagicColCount = Obj->MaxMagicColCount;
        }
    }

}
//----------------------------------------------------------------------------------------------------
void ObjectDataClass::SetRecipeLink( )
{
	//
	//01.武器（歸於武器表）
	//02.防具（歸於防具表）
	//03.食物（歸於物品表）
	//04.甜食（歸於物品表）
	//05.藥水（歸於物品表）
	//------------------------------------------------------------------------------
	GameObjDbStructEx	*Obj;
	GameObjDbStructEx	*ProduceObj;
	_ObjectDB.GetDataByOrder( true );
	for( int i = 0 ; i < _ObjectDB.TotalInfoCount() ; i++ )
	{
		Obj = _ObjectDB.GetDataByOrder();

		if( !Obj->IsRecipe() )
			continue;

		GameObjectRecipeStruct& Recipe = Obj->Recipe;

		for( int j = 0 ; j < 9 ; j++ )
		{
			ProduceObj = _ObjectDB.GetObj( Recipe.ItemAll[j].OrgObjID );
			if( ProduceObj == NULL )
				continue;
			if( ProduceObj->IsItem() == false )			
				continue;
			if( ProduceObj->Item.SrcRecipe != 0 )
				continue;

			if(		ProduceObj->IsArmor() 
				||	ProduceObj->IsWeapon() )
			{
					ProduceObj->Item.SrcRecipe = Obj->GUID;
			}
			else if( ProduceObj->IsItem_Pure() ) //純物品類
			{
				if(		ProduceObj->Item.ItemType == EM_ItemType_Food 
					||	ProduceObj->Item.ItemType == EM_ItemType_SweetFood       	
					||	ProduceObj->Item.ItemType == EM_ItemType_Water           	)
				{
					ProduceObj->Item.SrcRecipe = Obj->GUID;
				}			
			}
		}
	}

}
//----------------------------------------------------------------------------------------------------
void ObjectDataClass::SetEqAttributeLink( )
{
	//------------------------------------------------------------------------------
	for( int i = 0 ; i < 150 ; i++ )
	{
		for( int j = 0 ; j < 16 ; j++ )
		{
			_EqAttribute[j][i].clear();
		}
	}
	//------------------------------------------------------------------------------
    GameObjDbStructEx	*Obj;
	_ObjectDB.GetDataByOrder( true );
	for( int i = 0 ; i < _ObjectDB.TotalInfoCount() ; i++ )
	{
		Obj = _ObjectDB.GetDataByOrder();

		if( !Obj->IsAttribute() )
			continue;

		for( int j = 0 ; j < Obj->Attirbute.InheritLV_Range ; j++ )
		{
			int LV = j + Obj->Attirbute.InheritLV;
			if( LV > 150 )
				LV = 150;
			if( LV < 1 )
				LV = 1;
			for( int k = 0 ; k < 16 ; k++ )
			{
				if( TestBit( Obj->Attirbute.AddPos._Type , k ) )
					_EqAttribute[k][ LV - 1 ].push_back( Obj );
			}
		}
	}
}
//----------------------------------------------------------------------------------------------------
//設定天賦資料
int 	ObjectDataClass::GetItemAttribute(  int LV , AddonPosENUM AddonPos )
{
	if( (unsigned)LV >= 150 )
		return 0;
	if( (unsigned) AddonPos >= 16 )
		return 0;

	vector< GameObjDbStructEx* >& List = _EqAttribute[ AddonPos ][ LV ];		//附加屬性表
	if( List.size() == 0 )
		return 0;
	GameObjDbStructEx *Obj = List[ rand() % List.size() ];
	if( rand() % 10000 < Obj->Attirbute.InheritRate )
		return Obj->GUID;
	return 0;
}
//----------------------------------------------------------------------------------------------------
void ObjectDataClass::SetQuestLink()
{
    GameObjDbStructEx		*pObj;
	GameObjDbStructEx		*pQuestObj;
	GameObjectQuestDetail	*pQuest;
	GameObjectNpcStruct		*pNPC;

    _ObjectDB.GetDataByOrder( true );
    for( int i = 0 ; i < _ObjectDB.TotalInfoCount() ; i++ )
    {
        pQuestObj = _ObjectDB.GetDataByOrder();

		int iGuid = pQuestObj->GUID;

		if( iGuid == 100217 )
		{
			int a = 3;
		}
        
        if( !pQuestObj->IsQuest() )
		{
			if( pQuestObj->IsQuestNPC() )
			{
				if( pQuestObj->NPC.iQuestNPCRefID != 0 )
				{
					GameObjectNpcStruct RefObj;
					pObj	= _ObjectDB.GetObj( pQuestObj->NPC.iQuestNPCRefID );
					pNPC	= &pQuestObj->NPC;

					RefObj	= *pNPC;
					memcpy(  RefObj.iQuestID, pNPC->iQuestID, (sizeof(int)*20) );

					*pNPC	= pObj->NPC;

					pNPC->iQuestMode		= RefObj.iQuestMode;
					pNPC->szQuestNpcText	= RefObj.szQuestNpcText;
					pNPC->szQuestDoingText	= RefObj.szQuestDoingText;
					pNPC->iQuestNPCRefID	= RefObj.iQuestNPCRefID;

					memcpy( pNPC->iQuestID, RefObj.iQuestID, (sizeof(int)*20) );
				}
			}

            continue;
		}

		pQuest = &pQuestObj->QuestDetail;

		// 檢查任務中有無需要宰殺怪物, 若有則取出該 NPC 資料, 並設入任務關聯

		for( int i = 0; i < _MAX_SIZE_QUEST_ITEM; i++ )
		{
			int iObjID = 0;
			
			// 打倒目標後有機會得到任務物品

				iObjID = pQuest->iProcess_KilltoGetItem_ObjID[ i ];
			
				if( iObjID != 0 )
				{					
					pObj = _ObjectDB.GetObj( iObjID );
					
					if( pObj )
					{
						pNPC = &( pObj->NPC );

						bool bLinked = false;
						if( bLinked == false )
						{
							for( int i = 0; i < _MAX_QUESTLINK_COUNT; i++ )
							{
								if( pNPC->pQuestLink[ i ] == 0 )
								{
									bLinked = true;
									pNPC->pQuestLink[ i ] = pQuestObj;
									break;
								}
							}

							if( bLinked == false )
							{
								Print( LV5 , "SetQuestLink" , "NPC[ %d ][ %s ]與太多任務有所關連 ", pObj->GUID, pObj->Name );
							}
						}
					}
				}

			// 指定打倒目標計數

				iObjID = pQuest->iRequest_KillID[ i ];

				if( iObjID != 0 )
				{
					pObj = _ObjectDB.GetObj( iObjID );
					
					if( pObj )
					{
						bool bLinked = false;
						pNPC = &( pObj->NPC );

						// 先檢查該 NPC 是否已有建立與該任務的關連
						for( int i = 0; i < _MAX_QUESTLINK_COUNT; i++ )
						{
							if( pNPC->pQuestLink[ i ] == pQuestObj )
							{
								bLinked = true;
								break;
							}
						}
						
						if( bLinked == false )
						{
							for( int i = 0; i < _MAX_QUESTLINK_COUNT; i++ )
							{
								if( pNPC->pQuestLink[ i ] == 0 )
								{
									bLinked = true;
									pNPC->pQuestLink[ i ] = pQuestObj;
									break;
								}
							}

							if( bLinked == false )
							{
								Print( LV5 , "SetQuestLink" , "NPC[ %d ][ %s ]與太多任務有所關連 ", pObj->GUID, pObj->Name );
							}
						}
					}
				}

			// 點擊物件關連
				
				iObjID = pQuest->iProcess_ClickToGetItem_ObjID[ i ];
			
				if( iObjID != 0 )
				{					
					pObj = _ObjectDB.GetObj( iObjID );
					
					if( pObj )
					{
						bool bLinked = false;
						pNPC = &( pObj->NPC );

						// 先檢查該 NPC 是否已有建立與該任務的關連
						for( int i = 0; i < _MAX_QUESTLINK_COUNT; i++ )
						{
							if( pNPC->pQuestLink[ i ] == pQuestObj )
							{
								bLinked = true;
								break;
							}
						}
						
						if( bLinked == false )
						{
							for( int i = 0; i < _MAX_QUESTLINK_COUNT; i++ )
							{
								if( pNPC->pQuestLink[ i ] == 0 )
								{
									bLinked = true;
									pNPC->pQuestLink[ i ] = pQuestObj;
									break;
								}
							}

							if( bLinked == false )
							{
								Print( LV5 , "SetQuestLink" , "NPC[ %d ][ %s ]與太多任務有所關連 ", pObj->GUID, pObj->Name );
							}
						}
					}
				}
		}
	}
}
//----------------------------------------------------------------------------------------------------
const char*		ObjectDataClass::GetString( const char* Key )
{
	map< string , string >::iterator Iter;
	Iter = _StringMap.find( Key );
	if( Iter == _StringMap.end( ) )
	{
		return "";
	}
	return Iter->second.c_str();
}
//----------------------------------------------------------------------------------------------------
void ObjectDataClass::SetStringLink()
{
	GameObjDbStructEx	*Obj;
	DB_GameObjDbStruct	*TempDBObj = NULL;
	ReaderClass< DB_GameObjDbStruct >*		Reader;
	map<string,ReadInfoStruct>*             ReadInfo ;
	map<string,ReadInfoStruct>::iterator    Iter;
	char	KeyStr[256];
	char**	OutStr;

	int		ObjectOffest = int( &TempDBObj->GameData );

	_ObjectDB.GetDataByOrder( true );

	for( int i = 0 ; i < _ObjectDB.TotalInfoCount() ; i++ )
	{
		Obj = _ObjectDB.GetDataByOrder();

		if( Obj->IsNPC() )
		{
			if( Obj->IsQuestNPC() )
				Reader = Obj->ObjReader_QuestNPC( );
			else
				Reader = Obj->ObjReader_NPC( );
		}
		else if( Obj->IsItem() )
		{
			Reader = Obj->ObjReader_Item( );
		}
		else if( Obj->IsWeapon()		)
		{
			Reader = Obj->ObjReader_Weapon( );
		}
		else if( Obj->IsArmor()		)
		{
			Reader = Obj->ObjReader_Armor( );
		}
		else if( Obj->IsKeyItem()	)
		{
			Reader = Obj->ObjReader_KeyItem( );
		}
		else if( Obj->IsMine()		)
		{
			Reader = Obj->ObjReader_Mine( );
		}
		else if( Obj->IsMagicBase()		)
		{
			Reader = Obj->ObjReader_MagicBase( );
		}
		else if( Obj->IsShop()		)
		{
			Reader = Obj->ObjReader_Shop( );
		}
		else if( Obj->IsAttribute()	)
		{
			Reader = Obj->ObjReader_AddPower();
		}
		else if( Obj->IsFlagObj()	)
		{
			Reader = Obj->ObjReader_Flag( );
		}
		else if( Obj->IsRune()		)
		{
			Reader = Obj->ObjReader_Rune( );
		}
		else if( Obj->IsSuit()		)
		{
			Reader = Obj->ObjReader_Suit( );
		}
		else if( Obj->IsQuest()		)
		{
			Reader = Obj->ObjReader_QuestDetail( );
		}
		else if( Obj->IsBody() )
		{
			Reader = Obj->ObjReader_Body( );
		}
		else if( Obj->IsImage() )
		{
			Reader = Obj->ObjReader_Image( );
		}
		else if( Obj->IsLearnMagic() )
		{
			Reader = Obj->ObjReader_LearnMagic( );
		}
		else if( Obj->IsPlayer() )
		{
			Reader = Obj->ObjReader_Player( );
		}
		else if( Obj->IsTitle() )
		{
			Reader = Obj->ObjReader_Title( );
		}
		else if( Obj->IsRecipe() )
		{
			Reader = Obj->ObjReader_Recipe( );
		}

		ReadInfo = Reader->ReadInfo();
		for(    Iter  = ReadInfo->begin() ; 
			Iter != ReadInfo->end() ; 
			Iter++  )
		{
			ReadInfoStruct *IDData = &(Iter->second);

			switch(IDData->Type)
			{
			case ENUM_Type_CharStringPoint:
			case ENUM_Type_TextDataPoint:
				OutStr = (char**)(IDData->Point + int(Obj) - ObjectOffest );
				break;
			default :
				continue;
			}
			
			sprintf( KeyStr , "Sys%d_%s" , Obj->GUID , Iter->first.c_str() );
			*OutStr	= (char*)GetString( KeyStr );
		}
			
	}
}
#pragma managed