#include "stdafx.h"
#include "LoadStage.h"
#include "LoadUIManager.h"
#include "StageManager.h"
#include "ObjectManager.h"
#include "SoundSystem.h"

#include "Application.h"

#include "OptionManager.h"
#include "GameResourceManager.h"
#include "WorldManager.h"
#include "SceneManager.h"
#include "DramaturgyManager.h"
#include "GameUIManager.h"

#include "ItemManager.h"
#include "ItemDefine.h"

#include "ResourceManager.h"
#include "CoolTimeManager.h"

#include "Monster_Common.h"
#include "Npc_Common.h"
#include "Player_Common.h"

#include "NpcScript.h"
#include "MonsterScript.h"
#include "SkillScript.h"
#include "SkillManager.h"
#include "StageScript.h"

#include "hero.h"

#include "QuickManager.h"
#include "QuestManager.h"
#include "PVPManager.h"
#include "TitleManager.h"
#include "GuildManager.h"
#include "ItemMixManager.h"

#include "rendersystem.h"

//#ifdef _DEVSYS
//#include "DevSystem.h"
//#endif


cLoadStage::cLoadStage()
: mpLoadUIManager(0)
{
	mLoadState = eLOADSTATE_NONE;

	mLoadThread = 0;
}

cLoadStage::~cLoadStage()
{
}

void cLoadStage::Init( cStageManager* pStageManager )
{
	mpStageManager = pStageManager;
}

void cLoadStage::InitStage()
{
	if( mInit )	return;

	mpLoadUIManager = new cLoadUIManager;
	mpLoadUIManager->Init();

	mInit = true;
}

void cLoadStage::Exit()
{
	if( mLoadThread )
	{
		WaitForSingleObjectEx( mLoadThread, INFINITE, TRUE );
		CloseHandle(mLoadThread); 
		mLoadThread = NULL; 
	}

	SAFE_EXIT_DELETE( mpLoadUIManager );

	mpStageManager = NULL;
}

void cLoadStage::Open()
{
	RENDERSYS->SetWorldRendering( false );

	mMonsterClassCount = 0;
	mNpcClassCount = 0;

	mSkillCount = 0;
	mInfluenceCount = 0;

	mLoadState = eLOADSTATE_START;
	mLoadFlag.loadInfo = 0;

	/// ui
	mpLoadUIManager->Open( STAGEMAN->GetMapIdx() );
	PVPMAN->SetEnableBattle( false );

	/// 로딩이 완료 되었다면....
	if( NETWORK->IsConnected() )
	{
		MSGROOT msg;
		msg.Category = NM_USER;
		msg.Protocol = NM_USER_LOADDATA_REQ;
		NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
	}

	///
	mGoPercent = 0.0f;

#ifdef NOCONNECT_SERVER
	/// 맵정보를 로드한다.
	WORLDMAN->Init();
	WORLDMAN->Open();

	OBJECTMANAGER->AddHeroInfo( 0, "화제의인물", 0, 0 );
	mpStageManager->ChangeStage( eStage_Game );
#endif
}

void cLoadStage::Close()
{
	/// UI
	mpLoadUIManager->Close();

	if( mLoadThread )
	{
		WaitForSingleObjectEx( mLoadThread, INFINITE, TRUE );
		CloseHandle(mLoadThread); 
		mLoadThread = NULL; 
	}
}

void cLoadStage::ChangeLoadState( eLOADSTATE state )
{
	mLoadState = state;

	if( mLoadState == eLOADSTATE_GAMEINFO )
	{
		mGoPercent = 100.0f;
	}
	else if( mLoadState != eLOADSTATE_END )
	{
		mGoPercent = ((float)state/(float)eLOADSTATE_END)*100.0f;
	}

//	/// 
//#ifdef _DEVSYS
//	DEVSYSTEM->mLoadState = mLoadState;
//#endif
}

void cLoadStage::Process( unsigned long deltaTime, unsigned long /*accumTime*/ )
{
	if( mLoadState != eLOADSTATE_NONE )
	{
		if( mLoadState == eLOADSTATE_END )
		{
			if( mLoadFlag.flag.heroBaseInfoOn == false )
				return;
			if( mLoadFlag.flag.itemCoolTimeInfoOn == false )
				return;
			if( mLoadFlag.flag.shortcutInfoOn == false )
				return;
			if( mLoadFlag.flag.titleInfoOn == false )
				return;
			if( mLoadFlag.flag.questInfoOn == false )
				return;
			if( mLoadFlag.flag.optionInfoOn == false )
				return;
			if( mLoadFlag.flag.makeSkillInfoOn == false )
				return;

			/// 게임 진입 패킷을 준다..
			MSGROOT msg;
			msg.Category = NM_USER;
			msg.Protocol = NM_USER_GAMEIN_REQ;
			NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

			mLoadState = eLOADSTATE_NONE;
		}
		else if( mLoadState == eLOADSTATE_START )
		{
			ChangeLoadState(eLOADSTATE_CLEARINFO);

			DWORD threadId;
			mLoadThread = CreateThread( NULL, 0, LoadThreadStartFunc, (LPVOID)this, 0, &threadId );
			if( mLoadThread == NULL )
			{
				assert(0);
				LoadFaile( eLOADSTATE_START );
				return;
			}
			::Sleep(1);
		}
		else
		{
			::Sleep(10);
			bool end = mpLoadUIManager->UpdateLoadingGauge( deltaTime*0.05f, mGoPercent );
			if( mGoPercent == 100.0f && end == true )
				ChangeLoadState( eLOADSTATE_END );
		}
	}
	/// UI
	mpLoadUIManager->Process();
}

void cLoadStage::NetworkMsgParser( unsigned long /*connectionindex*/, char* pMsg, unsigned long /*length*/ )
{
	MSGROOT* pTemMsg = (MSGROOT*)pMsg;
	switch( pTemMsg->Category )
	{
	case NM_USER:
		{
			switch( pTemMsg->Protocol )
			{
			case NM_USER_GAMEIN_RES:
				{
					MSG_ERROR* msg = (MSG_ERROR*)pMsg;
					if( msg->ErrorCode == 0 )
					{
						/// 성공
						Msg_CharacterGameinAck( pTemMsg );
					}
					else
					{
						/// 실패 처리
						assert(0);
						return;
					}
				}
				break;
			}

		}break;
	case NM_MONSTER:
		{
			switch( pTemMsg->Protocol )
			{
			case NM_MONSTER_MODELNUMBER_RES:
				{
					MSG_MODELNUMBER* pmsg = (MSG_MODELNUMBER*)pMsg;

					mMonsterClassCount = pmsg->mCount;
					assert( mMonsterClassCount <= 50 );
					::memcpy( mMonsterClassIdx, pmsg->mClassIdx, sizeof(unsigned long) * mMonsterClassCount );

					mLoadFlag.flag.monsterModelOn = true;
				}
			}
		}break;
	case NM_NPC:
		{
			switch( pTemMsg->Protocol )
			{
			case NM_NPC_MODELNUMBER_RES:
				MSG_MODELNUMBER* pmsg = (MSG_MODELNUMBER*)pMsg;

				mNpcClassCount = pmsg->mCount;
				assert( mNpcClassCount <= 50 );
				::memcpy( mNpcClassIdx, pmsg->mClassIdx, sizeof(unsigned long) * mNpcClassCount );

				mLoadFlag.flag.npcModelOn = true;
			}
		}break;
	case NM_SKILL:
		{
			switch( pTemMsg->Protocol )
			{
				/// 070828 PKH 스킬로드
			case NM_SKILL_LIST_RES:
				{
					MSG_RES_SKILL_LIST* pmsg = (MSG_RES_SKILL_LIST*)pMsg;

					mSkillCount = pmsg->mRowCount;
					assert( mSkillCount <= 100 );
					::memcpy( mSkill, pmsg->mTable, sizeof(sHaveSkill) * mSkillCount );

					mLoadFlag.flag.skillInfoOn = true;
				}
				break;
			case NM_SKILL_INFLUENCE_LIST_RES:
				{
					MSG_RES_INFLUENCE_LIST* pmsg = (MSG_RES_INFLUENCE_LIST*)pMsg;

					mInfluenceCount = pmsg->mRowCount;
					assert( mInfluenceCount <= 100 );
					::memcpy( mInfluence, pmsg->mTable, sizeof(sInfluenceClient) * mInfluenceCount );

					mLoadFlag.flag.InfluenceInfoOn = true;
				}
				break;
			}
		}break;
	case NM_ITEM:
		{
			switch( pTemMsg->Protocol )
			{
			case NM_ITEM_INVENTORY_RES:
				{
					MSG_RES_INVENTORY* msgData = (MSG_RES_INVENTORY*)pMsg;
					sInventory*        inv = msgData->Inventory;

					/// ui 는 나중에 업데이트
					for( int i = 0, iend = msgData->RowCount; i < iend; ++i, inv++ )
					{
						ITEMMAN->NetSetItem( inv, false );
					}

					/// 정보 저장
					ITEMMAN->SetActiveWeapon( msgData->activeWeapon );

					mLoadFlag.flag.itemInfoOn = true;
				}
				break;
			case NM_ITEM_INVENTORY_COOLTIME_RES:
				{
					MSG_RES_INVENTORY_COOLTIME* msgData = (MSG_RES_INVENTORY_COOLTIME*)pMsg;

					for( int i = 0; i < msgData->RowCount; ++i )
					{
						sInventoryCooltime& cool = msgData->InventoryCooltime[i];
						COOLMAN->NetSetCool( cool );
					}

					mLoadFlag.flag.itemCoolTimeInfoOn = true;
				}
				break;
			}
		}
		break;
	case NM_PLAYER:
		{
			switch( pTemMsg->Protocol )
			{
			case NM_PLAYER_HEROINFO_RES:
				{
					if( HERO )
					{
						HERO->SetHeroInfoNet( (MSGROOT*)pMsg );
					}
					else
					{
						/// error check
						assert(0);
						LoadFaile( eLOADTATE_HEROBASEINFO );
						return;
					}
					mLoadFlag.flag.heroBaseInfoOn = true;
				}
				break;
			case NM_PLAYER_OPTION_VALUE_RES:
				{
					MSG_RES_PLAYER_OPTION_VALUE* msgData = (MSG_RES_PLAYER_OPTION_VALUE*)pMsg;
					OPTIONMAN->SetOptionValue( msgData->option1 );

					mLoadFlag.flag.optionInfoOn = true;
				}
				break;
			case NM_PLAYER_SHORTCUT_LIST_RES:
				{
					MSG_RES_PLAYER_SHORTCUT_LIST* msgData = (MSG_RES_PLAYER_SHORTCUT_LIST*)pMsg;

					for( int i = 0; i < MAX_SHORTCUT_SIZE; ++i )
					{
						sShortcut& shorCut = msgData->mShortcut[i];
						QUICKMAN->NetSetData( i, shorCut );
					}

					mLoadFlag.flag.shortcutInfoOn = true;
				}
				break;
			case NM_PLAYER_MONEY_RES:
				{
					MSG_RES_PLAYER_MONEY* msg = (MSG_RES_PLAYER_MONEY*)pMsg;
					HERO->SetMoney( msg->mMoney );
				}
				break;
			case NM_PLAYER_DEPOSIT_RES:
				{
					MSG_RES_PLAYER_DEPOSIT* msg = (MSG_RES_PLAYER_DEPOSIT*)pMsg;
					HERO->SetDeposit( msg->mDeposit );
				}
				break;
			case NM_PLAYER_TITLE_LIST_RES:
				{
					MSG_RES_PLAYER_TITLELIST* pmsg = (MSG_RES_PLAYER_TITLELIST*)pMsg;

					TITLEMAN->ClearList();

					for( int i = 0; i < pmsg->rowCount; ++i )
						TITLEMAN->AddHaveTitle( pmsg->mTitleIndex[i] );

					mLoadFlag.flag.titleInfoOn = true;
				}
				break;
			}
		}
		break;
	case NM_QUEST:
		{
			QUESTMAN->NetworkMsgParserLoad( pMsg );

			mLoadFlag.flag.questInfoOn = true;
		}
		break;
	case NM_MAKESKILL:
		{
			ITEMMIXMAN->NetworkMsgParserLoad( pMsg );

			mLoadFlag.flag.makeSkillInfoOn = true;
		}
		break;
	}
 }

void cLoadStage::Msg_CharacterGameinAck( MSGROOT* /*pMsg*/ )
{
	mpStageManager->ChangeStage( eStage_Game );

	HERO->GameIn( STAGEMAN->GetChannelIdx() );

	///
	GAMEUI->UpdateMinimap();

	/// 스킬 생성
	for( unsigned int i=0; i<mSkillCount; i++ )
	{
		sHaveSkill* inf = &mSkill[i];
		SKILLMAN->InitKeepSkill( inf );
	}

	/// 버프 및 디버프 윈도우 초기화
	for( unsigned int i=0; i<mInfluenceCount; i++ )
	{
		sInfluenceClient* inf = &mInfluence[i];
		cInfluenceObject* p = SKILLMAN->CreateInfluenceObject( inf->mUniqueIdx, inf->mInfluenceClassIdx, inf->mAuraSkillClassIdx, HERO, inf->mDieDelete );
		if( p )
		{
			p->StartProcess( inf->mRestTime, true );
		}
	}

	/// 퀵슬롯
	QUICKMAN->Open();

	/// 아이템 - 무게, 총갯수 갱신
	ITEMMAN->UpdateItem();

	///// 071024 PKH 스테이터스 재계산
	//HERO->NowCalcStatus();

	/// 퀘스트 매니저
	QUESTMAN->OpenLoad();

	/// Area Scene Data Loading
	SCENEMAN->LoadAreaGroup( HERO->GetMapNum() );

	/// Sound Scene Data Loading
	if( BeginSoundSceneLoad( HERO->GetMapNum() ) == true )
	{
		unsigned int loadCount = 0;
		if( SCENEMAN->LoadSoundSceneHeader( mFileLoader, loadCount ) == true && loadCount != 0 )
		{
			for(;;)
			{
				/// 씬로딩..
				int rVal = SCENEMAN->LoadSoundSceneNode( mFileLoader, 10 );
				if( rVal == -1 )
				{
					assert(0);
					break;
				}
				else if( rVal == 0 )
				{
					break;
				}
			}
		}
		mFileLoader.Close();
	}

	/// Map - Portal Data Loading
	{
		tPointerArray<void*>* pMapArray = STAGESCRIPT->GetMapChangeStarterArr( (unsigned short)HERO->GetMapNum() );
		if( pMapArray->IsEmpty() == false )
		{
			for( unsigned int i=0, end = pMapArray->GetSize(); i<end; ++i )
			{
				sStageChangePos* p = (sStageChangePos*)(*pMapArray)[i];

				NiPoint3 pos = NiPoint3( p->mPosX, p->mPosY,0.0f );
				if( WORLDMAN->CalcHeight( &pos.z, pos.x, pos.y ) == false )
				{
					assert(0);
					continue;
				}

				NiMatrix3 rot;
				rot.FromEulerAnglesXYZ( 0, 0, p->mRotAngle );
				SCENEMAN->CreateMapPortal( p->mPosIdx, pos, rot );
			}
		}
	}
}

bool cLoadStage::BeginSceneLoad( unsigned int mapIdx )
{
	unsigned long folderIdx = GAMERESOURCEMAN->GetMapFolderIdx( mapIdx );

	cString mapfile;
	mapfile.Format( "./Map/Map%02d/%03d.scene", folderIdx, folderIdx );

	/// 파일 열기
	if( mFileLoader.Open( mapfile.Cstr(), true ) == false )
	{
		assert( 0 && "failed to open file to load scene" );
		return false;
	}

	return true;
}

bool cLoadStage::BeginSoundSceneLoad( unsigned int mapIdx )
{
	unsigned long folderIdx = GAMERESOURCEMAN->GetMapFolderIdx( mapIdx );

	cString mapfile;
	mapfile.Format( "./Map/Map%02d/%03d.sound", folderIdx, folderIdx );

	/// 파일 열기
	if( mFileLoader.Open( mapfile.Cstr(), true ) == false )
	{
		return false;
	}

	return true;
}

void cLoadStage::LoadFaile( unsigned long error )
{
	mLoadState = eLOADSTATE_NONE;
	mFileLoader.Close();

	/// error message 출력후 종료
	TCHAR errormsg[255] = {0,};
	_stprintf( errormsg, _T( "State[%d] Data Load Error!!" ), error );

	::MessageBox( NULL, errormsg, _T("ERROR"), MB_OK );

	/// 프로그램 종료
	::SendMessage( THEAPP->GetHWND(), WM_CLOSE, 0, 0 );
}

DWORD cLoadStage::LoadThreadStartFunc( void* ptr )
{
	cLoadStage* stage = (cLoadStage*)ptr;
	return stage->LoadStageThread();
}

DWORD cLoadStage::LoadStageThread()
{
/*
	/// Waiting BGM Sound FadeOut 
	{
		for(;;)
		{
			if( SOUNDSYS->IsBGMFading() == false )
				break;
		}
	}
*/
	/// Map - Data Clear
	{
		WORLDMAN->Close();
		SCENEMAN->Clear();

		ChangeLoadState(eLOADSTATE_TERRAIN);
	}

	/// Terrain Data Loading
	{
		if( GAMERESOURCEMAN->IsMapUseTile( HERO->GetMapNum() ) == true )
		{
			if( WORLDMAN->LoadTerrainHeader( HERO->GetMapNum() ) == false )
			{
				LoadFaile( eLOADSTATE_TERRAIN );
				return 0;
			}

			for(;;)
			{
				int ret = WORLDMAN->LoadTerrainNodes( 30 );

				if( ret == -1 )
				{
					LoadFaile( eLOADSTATE_TERRAIN );
					return 0;
				}
				else if( ret == 1 )
					break;
			}
		}
		ChangeLoadState(eLOADSTATE_NAVIMESH);
	}

	/// NaviMesh Data Loading
	{
		if( WORLDMAN->LoadNaviMeshHeader( HERO->GetMapNum() ) == false )
		{
			LoadFaile( eLOADSTATE_NAVIMESH );
			return 0;
		}
		
		for(;;)
		{
			int ret = WORLDMAN->LoadNaviMeshNodes( 30 );

			if( ret == -1 )
			{
				LoadFaile( eLOADSTATE_NAVIMESH );
				return 0;
			}
			else if( ret == 1 )
			{
				break;
			}
		}
		ChangeLoadState(eLOADSTATE_NAVIFIELD);
	}

	/// NaviField Data Loading
	{
		if( WORLDMAN->LoadNaviField( HERO->GetMapNum() ) == false )
		{
			LoadFaile( eLOADSTATE_NAVIFIELD );
			return 0;
		}
		ChangeLoadState(eLOADSTATE_SCENE);
	}

	/// Scene Data Loading
	{
		if( BeginSceneLoad( HERO->GetMapNum() ) == false )
		{
			LoadFaile( eLOADSTATE_SCENE );
			return 0;
		}

		unsigned int loadCount = 0;
		if( SCENEMAN->LoadSceneHeader( mFileLoader, loadCount ) == false )
		{
			LoadFaile( eLOADSTATE_SCENE );
			return 0;
		}

		if( loadCount != 0 )
		{
			unsigned int checkCount = 0;
			/// 씬로딩..
			for(;;)
			{
				int rVal = SCENEMAN->LoadSceneNode( mFileLoader, 10 );
				if( rVal == -1 )
				{
					LoadFaile( eLOADSTATE_SCENE );
					return 0;
				}
				else if( rVal == 0 )
				{
					ChangeLoadState(eLOADSTATE_MONSTERDATA);
					break;
				}

				checkCount += 10;
				unsigned int per = (unsigned int)(100 * ((float)checkCount/(float)loadCount));

				switch( mLoadState )
				{
				case eLOADSTATE_SCENE: 
					{
						if( per / 20 > 0 ) 
							ChangeLoadState(eLOADSTATE_SCENE_PER1);
					}
					break;
				case eLOADSTATE_SCENE_PER1:
					{
						if( per / 40 > 0 ) 
							ChangeLoadState(eLOADSTATE_SCENE_PER2);
					}
					break;
				case eLOADSTATE_SCENE_PER2:
					{
						if( per / 60 > 0 ) 
							ChangeLoadState(eLOADSTATE_SCENE_PER3);
					}
					break;
				case eLOADSTATE_SCENE_PER3:
					{
						if( per / 80 > 0 ) 
							ChangeLoadState(eLOADSTATE_SCENE_PER4);
					}
					break;
				}
			}

			mFileLoader.Close();
		}
	}

	/// Map - Monster Data Loading
	{
		unsigned long errorCheck = 0;
		for(;;)
		{
			if( mLoadFlag.flag.monsterModelOn == true )
				break;

			errorCheck++;
			if( errorCheck == ULONG_MAX )
			{
				NiMessageBox("Not Recv Monster Data Msg","Loading Error");
				return 0;
			}
		}

		if( mMonsterClassCount != 0 )
		{
			for( unsigned int i=0;i<mMonsterClassCount; ++i )
			{
				/// 서버로 부터 받은 몬스터 종류로 부터 리소스를 생성한다.
				unsigned long idx = mMonsterClassIdx[i];

				sMonsterScript* info = MONSTERSCRIPT->GetMonsterListInfo( idx );
				if( info == 0 )
				{
					assert(0);
					continue;
				}

				const char* name = GAMERESOURCEMAN->GetModelFileName( info->mKfmIdx );
				if( name )
				{
					cString pathName;
					pathName.Format( "./Data/Monster/%s", name );

					RESOURCEMAN->LoadKFM( pathName );
				}
				else
				{
					assert(0);
					continue;
				}

				/// 몬스터 스킬에 대한 연출 객체 Load
				DRAMATURGYMAN->DirectLoadMonsterDramaObj( idx );
			}
		}

		ChangeLoadState(eLOADSTATE_NPCDATA);
	}

	/// Map - Npc Data Loading
	{
		unsigned long errorCheck = 0;
		for(;;)
		{
			if( mLoadFlag.flag.npcModelOn == true )
				break;

			errorCheck++;
			if( errorCheck == ULONG_MAX )
			{
				NiMessageBox("Not Recv Npc Data Msg","Loading Error");
				return 0;
			}
		}

		if( mNpcClassCount != 0 )
		{
			for( unsigned int i=0;i<mNpcClassCount;++i )
			{
				unsigned long idx = mNpcClassIdx[i];

				sNPCList* info = NPCSCRIPT->GetNPCList( idx );
				if( info == 0 )
				{
					assert(0);
					continue;
				}

				const char* name = GAMERESOURCEMAN->GetModelFileName( info->mModelIndex );
				if( name )
				{
					cString pathName;
					pathName.Format( "./Data/Npc/%s", name );

					RESOURCEMAN->LoadKFM( pathName );
				}
				else
				{
					assert(0);
					continue;
				}
			}
		}

		ChangeLoadState(eLOADSTATE_HEROITEM);
	}

	/// Hero Item Data Loading
	{
		unsigned long errorCheck = 0;
		for(;;)
		{
//			if( mLoadFlag.flag.heroBaseInfoOn == true && 
//				mLoadFlag.flag.itemInfoOn == true )
//				break;
			if( mLoadFlag.flag.itemInfoOn == true )
				break;

			errorCheck++;
			if( errorCheck == ULONG_MAX )
			{
				NiMessageBox("Not Recv Hero Item&BaseInfo Data Msg","Loading Error");
				return 0;
			}
		}

		for( unsigned int i=MIN_INVENTORY;i<MAX_INVENTORY;++i )
		{
			cItem& item = ITEMMAN->GetItem( i );
			cItemDefine* p = item.GetDefine();
			if( p )
			{
				const char* name1 = p->GetFileName0( HERO->GetRace(), HERO->GetGender() );
				const char* name2 = p->GetFileName1( HERO->GetRace(), HERO->GetGender() );
				cString pathName;

				if( name1 )
				{
					pathName.Format( "./Data/Character/%s", name1 );
					RESOURCEMAN->LoadNIF( pathName );
				}
				if( name2 )
				{
					pathName.Format( "./Data/Character/%s", name2 );
					RESOURCEMAN->LoadNIF( pathName );
				}
			}
		}

		ChangeLoadState(eLOADSTATE_BASESKILL);
	}

	/// Base Skill Data Loading
	{
		/// 기본공격 로딩
		for( unsigned long int ui= 0; ui< eRACE_MAX; ui++ )
		{
			for( unsigned int uj = 0; uj<eWEAPON_STATE_MAX;uj++ )
			{
				DRAMATURGYMAN->DirectLoadPlayerDramaObj( ui*10 + uj + 1 );
			}
		}

		ChangeLoadState(eLOADSTATE_HEROSKILL);
	}

	/// Hero Keep Skill Data Loading
	{
		unsigned long errorCheck = 0;
		for(;;)
		{
			if( mLoadFlag.flag.skillInfoOn == true ) 
				break;

			errorCheck++;
			if( errorCheck == ULONG_MAX )
			{
				NiMessageBox("Not Recv Hero Keep skill Data Msg","Loading Error");
				return 0;
			}
		}

		for( unsigned int i=0;i<mSkillCount;i++ )
		{
			sPlayerSkillBaseInfo* p = SKILLSCRIPT->GetPlayerSkillInfo( mSkill[i].mSkillIdx );
			if( p == 0 )
				continue;

			if( p->mType != eSKILLTYPE_PASSIVE )
				DRAMATURGYMAN->DirectLoadPlayerDramaObj( mSkill[i].mSkillIdx );
		}
	}

	/// Hero Keep Influence Data Loading
	{
		unsigned long errorCheck = 0;
		for(;;)
		{
			if( mLoadFlag.flag.InfluenceInfoOn == true ) 
				break;

			errorCheck++;
			if( errorCheck == ULONG_MAX )
			{
				NiMessageBox("Not Recv Hero Influence Data Msg","Loading Error");
				return 0;
			}
		}
	}

	ChangeLoadState( eLOADSTATE_GAMEINFO );

	return 0;
}
