#include "stdafx.h"
#include "ItemManager.h"
#include "CoolTimeManager.h"
#include "TarotManager.h"

#include "ObjectManager.h"
#include "QuickManager.h"
#include "Hero.h"
#include "GameUIManager.h"
#include "ChatManager.h"
#include "GameResourceManager.h"
#include "UIMsgboxEvent.h"
#include "NumberEditBox.h"
#include "Npc_Common.h"

#include "LootingWindow.h"
#include "NpcDisjointWindow.h"
#include "EnhancedWindow.h"
#include "TradeWindow.h"
#include "MoneyWindow.h"
#include "UserSellWindow.h"
#include "PutCardWindow.h"
#include "UserSellSearchWindow.h"
#include "CardBookWindow.h"
#include "TarotSheetWindow.h"

void cItemManager::NetworkMsgParser( char* msg )
{
	MSGROOT* tempMsg = (MSGROOT*)msg;

	switch( tempMsg->Protocol )
	{
	case NM_ITEM_MOV_INVENTORY_RES:
		{
			MSG_RES_ITEM_MOV_INVENTORY* msgData = (MSG_RES_ITEM_MOV_INVENTORY*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_MOV_INVENTORY_SUCCESS:
				NetTryItem( NM_ITEM_MOV_INVENTORY_RES );
				break;
			case ERROR_ITEM_MOV_INVENTORY_FAIL:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 222 ) );
				}
				break;
			case ERROR_ITEM_MOV_INVENTORY_NOTYET:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 223 ) );
				}
				break;
			case ERROR_ITEM_MOV_INVENTORY_MERGE:
				{
					/// move 잠금 풀고 merge 잠금 걸기
					if( mTry == ITEM_TRY_MOVE )
					{
						mLocked = false;
						mTry = ITEM_TRY_NULL;
					}
					else
					{
						assert(0);
					}

					///
					mLocked = true;
					mTry = ITEM_TRY_MERGE;
				}
				break;
			default:
				{
					assert(0);
				}
				break;
			}

			switch( mTry )
			{
			case ITEM_TRY_MOVE:
				UnlockItemTry( ITEM_TRY_MOVE );
				break;
			case ITEM_TRY_EQUIP:
				UnlockItemTry( ITEM_TRY_EQUIP );
				break;
			case ITEM_TRY_UNEQUIP:
				UnlockItemTry( ITEM_TRY_UNEQUIP );
				break;
			case ITEM_TRY_SPLIT:
				UnlockItemTry( ITEM_TRY_SPLIT );
				break;
			}
		}
		break;
	case NM_ITEM_MERGE_INVENTORY_RES:
		{
			MSG_RES_ITEM_MERGE_INVENTORY* msgData = (MSG_RES_ITEM_MERGE_INVENTORY*)msg;

			if( msgData->ErrorCode == ERROR_ITEM_MERGE_INVENTORY_SUCCESS )
				NetTryItem( NM_ITEM_MERGE_INVENTORY_RES );
			else
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 224 ) );

			UnlockItemTry( ITEM_TRY_MERGE );
		}
		break;
	case NM_ITEM_USE_INVENTORY_RES:
		{
			MSG_RES_ITEM_USE_INVENTORY* msgData = (MSG_RES_ITEM_USE_INVENTORY*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_USE_INVENTORY_SUCCESS:
				NetTryItem( NM_ITEM_USE_INVENTORY_RES );
				break;
			case ERROR_ITEM_USE_INVENTORY_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 225 ));
				break;
			case ERROR_ITEM_USE_INVENTORY_NOTYET:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 223 ));
				break;
			case ERROR_ITEM_USE_INVENTORY_COOLTIME:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 226 ));
				break;
			default:
				assert(0);
				break;
			}

			UnlockItemTry( ITEM_TRY_USE );
		}
		break;
	case NM_ITEM_DEL_INVENTORY_RES:
		{
			MSG_RES_ITEM_DEL_INVENTORY* msgData = (MSG_RES_ITEM_DEL_INVENTORY*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_DEL_INVENTORY_SUCCESS:
				NetTryItem( NM_ITEM_DEL_INVENTORY_RES );
				break;
			case ERROR_ITEM_DEL_INVENTORY_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 227 ) );
				break;
			case ERROR_ITEM_DEL_INVENTORY_NOTYET:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 223 ) );
				break;
			default:
				assert(0);
				break;
			}

			UnlockItemTry( ITEM_TRY_DUMP );
		}
		break;
	case NM_ITEM_SWI_INVENTORY_RES:
		{
			MSG_RES_ITEM_SWI_INVENTORY* msgData = (MSG_RES_ITEM_SWI_INVENTORY*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_SWI_INVENTORY_SUCCESS:
				NetSwitchWeapon( msgData->activeWeapon );
				break;
			case ERROR_ITEM_SWI_INVENTORY_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 228 ) );
				HERO->SetWeaponChangeFlag( false );
				break;
			case ERROR_ITEM_SWI_INVENTORY_NOTYET:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 223 ) );
				HERO->SetWeaponChangeFlag( false );
				break;
			default:
				assert(0);
				break;
			}

			UnlockItemTry( ITEM_TRY_SWITCH );
		}
		break;
	case NM_ITEM_DIVIDE_INVENTORY_RES:
		{
			MSG_RES_ITEM_DIVIDE_INVENTORY* msgData = (MSG_RES_ITEM_DIVIDE_INVENTORY*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_DIVIDE_INVENTORY_SUCCESS:
				NetTryItem( NM_ITEM_DIVIDE_INVENTORY_RES, msgData );
				break;
			case ERROR_ITEM_DIVIDE_INVENTORY_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 229 ) );
				break;
			case ERROR_ITEM_DIVIDE_INVENTORY_NOTYET:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 223 ) );
				break;
			default:
				assert(0);
				break;
			}

			UnlockItemTry( ITEM_TRY_SPLIT );
		}
		break;
	case NM_ITEM_ENHANCED_START_RES:
		{
			MSG_ERROR* msgData = (MSG_ERROR*)msg;

			cEnhancedWindow* win = GAMEUI->GetEnhancedWindow();

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_ENHANCED_START_SUCCESS:
				{
					HERO->SetStopFlag( eSTOP_ENHANCED );
					HERO->SetItemEnhanceEffect();

					if( win )
						win->StartGauge();
				}
				break;
			case ERROR_ITEM_ENHANCED_START_FAIL:
				{
					UIMAN->CreateModal(	eStage_Game,
						eMBEVENT_NONE, 
						GAMERESOURCEMAN->GetGameText( 254 ),	// 
						GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
						eSKIN_OK
						);
				}
				break;
			}

			if( win )
				win->NetUnLock();

			UnlockItemTry( ITEM_TRY_ENHANCEDSTART );
		}
		break;
	case NM_ITEM_ENHANCED_END_RES:
		{
			/// 강화
			MSG_RES_ITEM_ENHANCED_END* msgData = (MSG_RES_ITEM_ENHANCED_END*)msg;

			HERO->ClearItemEnhanceEffect();
			HERO->SetStopFlag( eSTOP_NONE );
			HERO->SetState( eOBJECT_STATE_IDLE );

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_ENHANCED_END_SUCCESS:
				{
					NetTryItem( NM_ITEM_ENHANCED_END_RES, msgData );
				}
				break;
			case ERROR_ITEM_ENHANCED_END_FAIL:
				{
					UIMAN->CreateModal(	eStage_Game,
						eMBEVENT_NONE, 
						GAMERESOURCEMAN->GetGameText( 254 ),	// 
						GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
						eSKIN_OK
						);
				}
				break;
			case ERROR_ITEM_ENHANCED_END_NOTYET:
				{
					UIMAN->CreateModal(	eStage_Game,
						eMBEVENT_NONE, 
						GAMERESOURCEMAN->GetGameText( 255 ),	// 
						GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
						eSKIN_OK
						);
				}
				break;
			}

			/// 윈도우 클리어
			cEnhancedWindow* p = GAMEUI->GetEnhancedWindow();
			if( p )
			{
				if( msgData->ErrorCode != ERROR_ITEM_ENHANCED_END_SUCCESS )
					p->Clear( false );

				p->NetUnLock();
			}

			UnlockItemTry( ITEM_TRY_ENHANCEDEND );
		}
		break;
	case NM_ITEM_ENHANCED_START_SYN:
		{
			MSG_SYN_ITEM_ENHANCED_START* msgData = (MSG_SYN_ITEM_ENHANCED_START*)msg;

			cPlayer* p = OBJECTMAN->GetPlayer( msgData->mCharacterIdx );
			if( p != NULL )
			{
				p->SetStopFlag( eSTOP_ENHANCED );
				p->SetItemEnhanceEffect();
			}
		}
		break;
	case NM_ITEM_ENHANCED_END_SYN:
		{
			MSG_SYN_ITEM_ENHANCED_END* msgData = (MSG_SYN_ITEM_ENHANCED_END*)msg;

			cPlayer* p = OBJECTMAN->GetPlayer( msgData->mCharacterIdx );
			if( p != NULL )
			{
				p->SetStopFlag( eSTOP_NONE );
				p->SetState( eOBJECT_STATE_IDLE );
				p->ClearItemEnhanceEffect();

				NiTransform trans;
				trans.MakeIdentity();
				trans.m_Translate = NiPoint3( 0.0f, 0.0f, 0.0f );

				if( msgData->ErrorCode == ERROR_ITEM_ENHANCED_END_SUCCESS )
				{
					p->SetLinkdEffect( eLINK_FOOT, "./Data/Effect/eff_enhance_s.nif", &trans, false, false );
					p->ChangeAnimation( (ePLAYER_ANIMATIONTYPE) 817 );
				}
				else
				{
					p->SetLinkdEffect( eLINK_BODY, "./Data/Effect/eff_enhance_f.nif", &trans, false, false );
					p->ChangeAnimation( (ePLAYER_ANIMATIONTYPE) 818 );
				}
			}
		}
		break;
	case NM_ITEM_ENHANCED_CANCEL_SYN:
		{
			MSG_SYN_ITEM_ENHANCED_CANCEL* msgData = (MSG_SYN_ITEM_ENHANCED_CANCEL*)msg;

			cPlayer* p = OBJECTMAN->GetPlayer( msgData->mCharacterIdx );
			if( p != NULL )
			{
				p->ClearItemEnhanceEffect();
				p->SetStopFlag( eSTOP_NONE );
				p->SetState( eOBJECT_STATE_IDLE );
			}
		}
		break;
	case NM_ITEM_DISJOINT_INVENTORY_RES:
		{
			/// 분해
			MSG_RES_ITEM_DISJOINT_INVENTORY* msgData = (MSG_RES_ITEM_DISJOINT_INVENTORY*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_DISJOINT_INVENTORY_SUCCESS:
				{
					NetTryItem( NM_ITEM_DISJOINT_INVENTORY_RES, msgData );
				}
				break;
			case ERROR_ITEM_DISJOINT_INVENTORY_FAIL:
				{
					UIMAN->CreateModal(	eStage_Game,
						eMBEVENT_NONE, 
						GAMERESOURCEMAN->GetGameText( 251 ),	// 
						GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
						eSKIN_OK
						);
				}
				break;
			case ERROR_ITEM_DISJOINT_INVENTORY_NOTYET:
				{
					UIMAN->CreateModal(	eStage_Game,
						eMBEVENT_NONE, 
						GAMERESOURCEMAN->GetGameText( 252 ),	// 
						GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
						eSKIN_OK
						);
				}
				break;
			}

			/// 윈도우 클리어
			cNpcDisjointWindow* p = GAMEUI->GetNpcDisjointWindow();
			if( p )
			{
				p->Clear();	/// 내부에서 netunlock
			}
			else
			{
				assert(0);
			}

			UnlockItemTry( ITEM_TRY_DISJOINT );
		}
		break;
	case NM_ITEM_DROP_IN_SYN:
	case NM_ITEM_SIGHT_IN_RES:
		{
			MSG_ITEM_INFO*	msgData = (MSG_ITEM_INFO*)msg;
			if(	CreateDropItem( msgData ) == false )
			{
				assert(0);
			}
		}
		break;
	case NM_ITEM_DROP_OUT_SYN:
	case NM_ITEM_SIGHT_OUT_RES:
		{
			MSG_ITEMIDX* msgData = (MSG_ITEMIDX*)msg;
			DeleteDropItem( msgData->idx );
		}
		break;
	case NM_ITEM_GET_OPEN_RES:
		{
			/// 아이템 리스트 요청
			MSG_RES_ITEM_GET_OPEN* msgData = (MSG_RES_ITEM_GET_OPEN*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_GET_OPEN_SUCCESS:
				{
					/// UI 에 아이템 리스트 세팅
					cLootingWindow* looting = GAMEUI->GetLootingWindow();
					if( looting )
					{
						/// 데이터 삭제
						looting->Clear();

						sItemData* data = msgData->itemData;
						for( int i = 0; i < msgData->rowCount; ++i, ++data )
						{
							looting->AddItem( (sLootData*)data );
						}

						GAMEUI->ShowLootingWindow();
					}
					else
					{
						assert(0);
					}
				}
				break;

				/// 상태... idle
			case ERROR_ITEM_GET_OPEN_FAIL:
				{
					/// 실패
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 210 ) );
				}
				break;
			case ERROR_ITEM_GET_OPEN_OWN:
				{
					/// 소유권오류
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 211 ) );
				}
				break;
			case ERROR_ITEM_GET_OPEN_DISTANCE:
				{
					/// 거리오류
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 212 ) );
				}
				break;
			case ERROR_ITEM_GET_OPEN_EXIST:
				{
					/// 열람중오류
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 213 ) );
				}
				break;
			default:
				assert(0);
				break;
			}

			UnlockItemTry( ITEM_TRY_PICK );
		}
		break;
	case NM_ITEM_GET_OPEN_SYN:
		{
			MSG_SYN_ITEM_GET_OPEN* msgData = (MSG_SYN_ITEM_GET_OPEN*)msg;
			cPlayer* player = OBJECTMAN->GetPlayer( msgData->characterIdx );
			if( player )
				player->SetState( ePLAYER_STATE_ITEMPICK );
		}
		break;
	case NM_ITEM_GET_CLOSE_RES:
		{
			/// 무조건 상자 닫기
			cLootingWindow* looting = GAMEUI->GetLootingWindow();
			if( looting )
			{
				/// 닫기만한다 ( 닫기 패킷은 안보냄 )
				looting->Close();

				/// 상태... idle
				if( HERO->GetState() == ePLAYER_STATE_ITEMPICK )
					HERO->SetState( eOBJECT_STATE_IDLE );
			} 
			else
				assert(0);
		}
		break;
	case NM_ITEM_GET_CLOSE_SYN:
		{
			MSG_SYN_ITEM_GET_CLOSE* msgData = (MSG_SYN_ITEM_GET_CLOSE*)msg;

			cPlayer* player =OBJECTMAN->GetPlayer( msgData->characterIdx );
			if( player && player->GetState() == ePLAYER_STATE_ITEMPICK )
			{
				player->SetState( eOBJECT_STATE_IDLE );
			}
		}
		break;
	case NM_ITEM_GET_RES:
		{
			/// 아이템 획득
			MSG_RES_ITEM_GET* msgData = (MSG_RES_ITEM_GET*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_GET_SUCCESS:
				NetTryItem( NM_ITEM_GET_RES, msgData );
				break;
			case ERROR_ITEM_GET_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_GETITEM, GAMERESOURCEMAN->GetGameText( 234 ) );
				break;
			case ERROR_ITEM_GET_AUTO:	/// 자동습득인 경우 처리
				NetGetItem( (MSG_RES_ITEM_GET*)msg );
				return;
			default:
				assert( 0 && "network error!" );
				break;
			}

			UnlockItemTry( ITEM_TRY_GET );

			cLootingWindow* win = GAMEUI->GetLootingWindow();
			if( win )
			{
				win->NetUnLock( eLOCK_GETITEM );
			}
			else
			{
				assert(0);
			}
		}
		break;
	case NM_ITEM_GET_LEAVE_RES:
		{
			/// 아이템 획득후, 루팅창에 남은 상태 
			MSG_RES_ITEM_GET_LEAVE* msgData = (MSG_RES_ITEM_GET_LEAVE*)msg;

			/// 남은 내용 세팅
			cLootingWindow* looting = GAMEUI->GetLootingWindow();
			if( looting )
			{
				/// 데이터 삭제
				looting->Clear();

				sItemData* data = msgData->itemData;
				for( int i = 0; i < msgData->rowCount; ++i, ++data )
				{
					looting->AddItem( (sLootData*)data );
				}

				if( msgData->rowCount <= 0 )
				{
					looting->Hide();
					if( HERO->GetState() == ePLAYER_STATE_ITEMPICK )
						HERO->SetState( eOBJECT_STATE_IDLE );
				}
			}
			else
			{
				assert(0);
			}
		}
		break;
	case NM_ITEM_GATHERING_OPEN_RES:
		{
			/// 채집 상자열기
			MSG_RES_ITEM_GATHERING_OPEN* msgData = (MSG_RES_ITEM_GATHERING_OPEN*)msg;

			/// UI 에 아이템 리스트 세팅
			cLootingWindow* looting = GAMEUI->GetLootingWindow();
			if( looting )
			{
				/// 데이터 삭제
				looting->Clear();

				sItemData* data = msgData->itemData;
				for( int i = 0; i < msgData->rowCount; ++i, ++data )
				{
					looting->AddItem( (sLootData*)data );
				}

				GAMEUI->ShowLootingWindow();
			}
			else
			{
				assert(0);
			}
		}
		break;
	case NM_ITEM_USE_RES:
		{
			/// 아이템이 사용됨 ( 스킬에 의한 사용등 )
			MSG_RES_ITEM_USE* msgData = (MSG_RES_ITEM_USE*)msg;

			sInventory* inv = &msgData->inventory;
			if( inv->count > 0 )
			{
				NetSetItem( inv );

				/// 쿨타임매니저에 사용 등록
				cItem& item = mItemArray[inv->number];
				cItemDefine* itemDefine = item.mDefine;
				if( itemDefine )
				{
					cItemAbility* itemAbil = itemDefine->GetAbililty();
					if( itemAbil && itemAbil->GetCoolTime() > 0 )
					{
						COOLMAN->StartCoolTime( item.mIndex );
					}
				}

				/// 아이템관련 정보 갱신
				UpdateItem();
			}
			else
			{
				NetDumpItem( inv->number );
			}

			/// 스킬사용으로 인한 아이템 사용이므로, unlock 하면 안됨!!! 
			/// lock, unlock 은 인벤토리,창고 등에서 아이템 에 관한 내용일때만 사용
		}
		break;
	case NM_ITEM_REWARD_RES:
		{
			/// 퀘스트로 인한 LOCK은 퀘스트에서 푼다
			/// 에러메세지는 퀘스트 보상에서 처리
			/// 아이템 획득 - 퀘스트 보상, 신규퀘스트시 아이템 제공
			MSG_RES_ITEM_REWARD* msgData = (MSG_RES_ITEM_REWARD*)msg;
			NetTryItem( NM_ITEM_REWARD_RES, msgData );
		}
		break;
	case NM_ITEM_TAKE_RES:
		{
			/// 퀘스트로 인한 LOCK은 퀘스트에서 푼다
			/// 아이템 회수 
			MSG_RES_ITEM_TAKE* msgData = (MSG_RES_ITEM_TAKE*)msg;
			NetTryItem( NM_ITEM_TAKE_RES, msgData );
		}
		break;
	case NM_ITEM_GET_QUEST_RES:
		{
			/// 아이템 자동습득이므로 lock 안함
			MSG_RES_ITEM_GET_QUEST* msgData = (MSG_RES_ITEM_GET_QUEST*)msg;

			/// 퀘스트 아이템 자동습득 처리!!
			sInventory* inv = &msgData->Inventory;

			/// 추가된 갯수 구하기
			cItem& item = mItemArray[inv->number];
			int addcount = inv->count - item.mCount;

			/// 갯수 및 무게 추가 안함
			NetSetItem( inv );

			/// 아이템 획득메세지 쏘기 
			cItemDefine* itemDefine = GetItemDefine( item.mIndex );
			if( itemDefine )
			{
				cStringT str;
				LPCTSTR countStr = cNumberEditBox::FormatNumber( addcount );

				str.Format( GAMERESOURCEMAN->GetGameText( 240 ), countStr );
				CHATMANAGER->AddItemMsg( item.mIndex, inv->number, GAMERESOURCEMAN->GetGameText( 245 ), (LPCTSTR)str.Cstr(), true );
			}

			/// 아이템관련 정보 갱신
			UpdateItem();
		}
		break;
	case NM_ITEM_EXCHANGE_ASK_RES:
		{
			cStringT str;

			/// 거래신청 결과
			MSG_RES_ITEM_EXCHANGE_ASK* msgData = (MSG_RES_ITEM_EXCHANGE_ASK*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_EXCHANGE_ASK_SUCCESS:	// 성공 - 신청후 대기중
				str.Format( GAMERESOURCEMAN->GetGameText( 2000 ), mTradeName.Cstr() );
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, (LPCTSTR)str.Cstr() );

				/// 거래 신청 완료시 상태 변경
				HERO->SetStopFlag( eSTOP_EXCHANGE );
				break;
			case ERROR_ITEM_EXCHANGE_ASK_FAIL:		// 실패 - 대상이 없거나 오류인경우
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2015 ) );
				break;
			case ERROR_ITEM_EXCHANGE_ASK_EXIST:		// 실패 - 이미 거래중
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2016 ) );
				break;
			case ERROR_ITEM_EXCHANGE_ASK_DISTANCE:	// 실패 - 거리
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2017 ) );
				break;
			case ERROR_ITEM_EXCHANGE_ASK_OPTIONREFUSE:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2700 ) );
				break;
			case ERROR_ITEM_EXCHANGE_ASK_REPLAY:	// 답변요청
				{
					/// 상대방으로부터 거래요청이 옴 
					/// 거래요청 메세지 박스 띄우기
					cPlayer* target = OBJECTMAN->GetPlayer( msgData->characterIdx );
					if( !target )
					{
						assert(0);
						return;
					}

					/// 
					str.Format( GAMERESOURCEMAN->GetGameText( 2001 ), target->GetName() );
					UIMAN->CreateModal(	eStage_Game,
						eMBEVENT_TRADE_REQUEST, 
						(LPCTSTR)str.Cstr(),			
						GAMERESOURCEMAN->GetGameText( 301 ),
						eSKIN_YESNO,
						0, 
						TRADE_WAIT_TIME,
						false, false );

					/// 상대정보세팅
					mTradeTarget = msgData->characterIdx;
					mTradeName = target->GetName();
				}
				break;
			}
		}
		break;
	case NM_ITEM_EXCHANGE_REP_RES:
		{
			/// 거래요청 응답에 관한 결과
			MSG_RES_ITEM_EXCHANGE_REP* msgData = (MSG_RES_ITEM_EXCHANGE_REP*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_EXCHANGE_REP_SUCCESS:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2002 ) );

					/// 거래 시작 
					cTradeWindow* trade = GAMEUI->GetTradeWindow();
					if( trade )
					{	
						trade->SetNames( (LPCTSTR)mTradeName.Cstr() );
						trade->ShowTop();
						GAMEUI->ShowInventoryWindow();

						/// 거래중 상태로 변경
						HERO->SetStopFlag( eSTOP_EXCHANGE );
					}
					else
					{
						assert(0);
					}
				}
				break;
			case ERROR_ITEM_EXCHANGE_REP_FAIL:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2003 ) );
					HERO->SetStopFlag( eSTOP_NONE );
					HERO->SetState( eOBJECT_STATE_IDLE );
				}
				break;
			case ERROR_ITEM_EXCHANGE_REP_NOTEXIST:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2004 ) );
					HERO->SetStopFlag( eSTOP_NONE );
					HERO->SetState( eOBJECT_STATE_IDLE );
				}
				break;
			}
		}
		break;
	case NM_ITEM_EXCHANGE_ADD_RES:
		{
			/// 거래아이템 추가 결과
			MSG_RES_ITEM_EXCHANGE_ADD* msgData = (MSG_RES_ITEM_EXCHANGE_ADD*)msg;

			cTradeWindow* trade = GAMEUI->GetTradeWindow();
			if( !trade )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_EXCHANGE_ADD_SUCCESS:		/// 등록완료
				if( mTry == ITEM_TRY_TRADEADD )
				{
					/// 아이템 등록이었으면,
					if( trade && trade->AddMyItem( mSlotIndex0 ) == false )
					{
						assert(0);
					}

					mSlotIndex0 = 0;
				}
				else
				{
					/// 금액 등록이었으면,
					if( trade )
						trade->AddMyMoney( mTradeMoney );
				}
				break;
			case ERROR_ITEM_EXCHANGE_ADD_FAIL:	/// 실패
				if( mTry == ITEM_TRY_TRADEADD )
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2008 ) );
				else
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2018 ) );
				break;
			}

			/// 락풀기
			if( mTry == ITEM_TRY_TRADEADD )
			{
				UnlockItemTry( ITEM_TRY_TRADEADD );
				if( trade )
					trade->NetUnLock();
			}
			else
			{
				/// 금액 윈도우 락 풀기
				cMoneyWindow* win = GAMEUI->GetMoneyWindow();
				if( win )
					win->NetUnLock();
			}
		}
		break;
	case NM_ITEM_EXCHANGE_ADD_SYN:
		{
			/// 상대방 아이템 추가
			MSG_SYN_ITEM_EXCHANGE_ADD* msgData = (MSG_SYN_ITEM_EXCHANGE_ADD*)msg;

			cTradeWindow* trade = GAMEUI->GetTradeWindow();
			if( !trade )
			{
				assert(0);
			}

			/// 아이템 등록
			if( msgData->type == TYPE_ITEM_EXCHANGE_ADD_ITEM )
			{
				if( trade )
					trade->AddThatItem( &msgData->inventory );
			}
			/// 금액 등록
			else
			{
				if( trade )
					trade->AddThatMoney( msgData->money );
			}
		}
		break;
	case NM_ITEM_EXCHANGE_DEL_RES:
		{
			/// 아이템 삭제 결과
			MSG_RES_ITEM_EXCHANGE_DEL* msgData = (MSG_RES_ITEM_EXCHANGE_DEL*)msg;

			cTradeWindow* trade = GAMEUI->GetTradeWindow();
			if( !trade )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_EXCHANGE_DEL_SUCCESS:
				if( mTry == ITEM_TRY_TRADEDELETE )
				{
					/// 아이템 삭제
					/// mSlotIndex0 : 거래삭제 슬롯은 예외로, 트레이드 슬롯을 사용한다
					/// 거래 슬롯 배열 인덱스
					if( trade && trade->DeleteMyItem( mTempIndex ) == false )
					{
						assert(0);
						return;
					}
				}
				break;
			case ERROR_ITEM_EXCHANGE_DEL_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2009 ) );
				break;
			}

			UnlockItemTry( ITEM_TRY_TRADEDELETE );
			if( trade )
				trade->NetUnLock();
		}
		break;
	case NM_ITEM_EXCHANGE_DEL_SYN:
		{
			/// 상대방 아이템 삭제 
			MSG_SYN_ITEM_EXCHANGE_DEL* msgData = (MSG_SYN_ITEM_EXCHANGE_DEL*)msg;

			cTradeWindow* trade = GAMEUI->GetTradeWindow();
			if( trade )
			{
				/// 아이템 삭제
				trade->DeleteThatItem( &msgData->inventory );
			}
			else
			{
				assert(0);
			}
		}
		break;
	case NM_ITEM_EXCHANGE_OK_RES:
		{
			/// 거래물품 확인 
			MSG_RES_ITEM_EXCHANGE_OK* msgData = (MSG_RES_ITEM_EXCHANGE_OK*)msg;

			cTradeWindow* trade = GAMEUI->GetTradeWindow();
			if( !trade )
			{
				assert(0);
			}

			if( trade && msgData->ErrorCode != ERROR_ITEM_EXCHANGE_OK_PLAYER )
				trade->NetUnLock();

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_EXCHANGE_OK_SUCCESS:
				{
					/// 물품확인 처리
					if( trade )
						trade->SetStatus( ItemExchangeOk, true );
				}
				break;
			case ERROR_ITEM_EXCHANGE_OK_FAIL:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2010 ) );

					/// 물품수정상태 처리
					if( trade )
						trade->SetStatus( ItemExchangeBegin, true );
				}
				break;
			case ERROR_ITEM_EXCHANGE_OK_PLAYER:		/// 상대방의 물품 확인 됨
				{
					if( trade )
						trade->SetStatus( ItemExchangeOk, false );
				}
				break;
			}
		}
		break;
	case NM_ITEM_EXCHANGE_RETRY_RES:
		{
			/// 거래물품 수정
			MSG_RES_ITEM_EXCHANGE_RETRY* msgData = (MSG_RES_ITEM_EXCHANGE_RETRY*)msg;

			cTradeWindow* trade = GAMEUI->GetTradeWindow();
			if( !trade )
			{
				assert(0);
			}

			if( trade && msgData->ErrorCode != ERROR_ITEM_EXCHANGE_RETRY_PLAYER )
				trade->NetUnLock();

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_EXCHANGE_RETRY_SUCCESS:
				{
					if( trade )
						trade->SetStatus( ItemExchangeBegin, true );
				}
				break;
			case ERROR_ITEM_EXCHANGE_RETRY_FAIL:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2011 ) );

					if( trade )
						trade->SetStatus( ItemExchangeOk, true );
				}
				break;
			case ERROR_ITEM_EXCHANGE_RETRY_PLAYER:	/// 상대방의 물품 수정상태 됨
				{
					if( trade )
						trade->SetStatus( ItemExchangeBegin, false );
				}
				break;
			}
		}
		break;
	case NM_ITEM_EXCHANGE_CANCEL_RES:
		{
			MSG_RES_ITEM_EXCHANGE_CANCEL* msgData = (MSG_RES_ITEM_EXCHANGE_CANCEL*)msg;

			cTradeWindow* trade = GAMEUI->GetTradeWindow();
			if( !trade )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_EXCHANGE_CANCEL_SUCCESS:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2005 ) );
				break;
			case ERROR_ITEM_EXCHANGE_CANCEL_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2007 ) );
				break;
			case ERROR_ITEM_EXCHANGE_CANCEL_PLAYER:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2006 ) );
				break;
			}

			if( msgData->ErrorCode != ERROR_ITEM_EXCHANGE_CANCEL_FAIL )
			{
				/// 거래 닫기
				if( trade )
					trade->Hide();

				/// 클리어
				mTradeName.Clear();
				mTradeTarget = 0;

				/// 상태 변경
				HERO->SetStopFlag( eSTOP_NONE );
				HERO->SetState( eOBJECT_STATE_IDLE );
			}

			if( trade && msgData->ErrorCode != ERROR_ITEM_EXCHANGE_CANCEL_PLAYER )
				trade->NetUnLock();
		}
		break;
	case NM_ITEM_EXCHANGE_END_RES:
		{
			/// 거래 종료
			MSG_RES_ITEM_EXCHANGE_END* msgData = (MSG_RES_ITEM_EXCHANGE_END*)msg;

			cTradeWindow* trade = GAMEUI->GetTradeWindow();
			if( !trade )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_EXCHANGE_END_SUCCESS:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2012 ) );

					/// 거래 아이템 삽입 및 거래된 아이템 삭제
					NetTradeItem( msgData );

					/// 거래윈도우 닫기
					if( trade )
						trade->Hide();

					/// 상태변경
					HERO->SetStopFlag( eSTOP_NONE );
					HERO->SetState( eOBJECT_STATE_IDLE );
				}
				break;
			case ERROR_ITEM_EXCHANGE_END_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2013 ) );
				break;
			case ERROR_ITEM_EXCHANGE_END_WAIT:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2014 ) );
				break;
			}

			if( trade )
				trade->NetUnLock();

			if( msgData->ErrorCode == ERROR_ITEM_EXCHANGE_END_WAIT )
			{
				if( trade )
					trade->SetStatus( ItemExchangeEnd, true );
			}
		}
		break;
	case NM_ITEM_STALL_SELL_OPEN_RES:
		{
			/// 노점상 오픈 요청 결과
			MSG_RES_ITEM_STALL_SELL_OPEN* msgData = (MSG_RES_ITEM_STALL_SELL_OPEN*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_OPEN_SUCCESS:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2500 ) );

					/// 판매노점상 open 상태로 함
					if( userSell )
					{
						userSell->SetStatus( eUSERSELL_SELL );
						userSell->SetOpen();
						userSell->SetName( (LPTSTR)mUserSellName.Cstr() );
						userSell->ShowTop();

						GAMEUI->ShowInventoryWindow();
					}

					/// 상태 변경
					HERO->SetStopFlag( eSTOP_OPENSTALL );
					HERO->ActiveUserSellBubble( (LPTSTR)mUserSellName.Cstr(), eCOLOR_GREEN );
				}
				break;
			case ERROR_ITEM_STALL_SELL_OPEN_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2501 ) );
				break;
			case ERROR_ITEM_STALL_SELL_OPEN_EXIST:		/// 이미 오픈중
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2502 ) );
				break;
			}

			if( userSell )
				userSell->NetUnLock( eLOCK_REGIST );
		}
		break;
	case NM_ITEM_STALL_SELL_OPEN_SYN:
		{
			/// 다른유저가 노점상 열고 있음
			MSG_SYN_ITEM_STALL_SELL_OPEN* msgData = (MSG_SYN_ITEM_STALL_SELL_OPEN*)msg;

			cPlayer* p = OBJECTMAN->GetPlayer( msgData->characterIdx );
			if( p )
			{
				p->SetState( eOBJECT_STATE_STOP );
				p->SetStopFlag( eSTOP_OPENSTALL );
				p->ActiveUserSellBubble( msgData->title, eCOLOR_GREEN );
			}
		}
		break;
	case NM_ITEM_STALL_SELL_RENAME_RES:
		{
			/// 노점명 변경결과
			MSG_RES_ITEM_STALL_SELL_RENAME* msgData = (MSG_RES_ITEM_STALL_SELL_RENAME*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_RENAME_SUCCESS:
				{
					/// 노점명 변경 성공
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2515 ) );

					/// 노점면 변경
					if( userSell )
						userSell->SetName( (LPTSTR)mUserSellName.Cstr() );

					/// 상태 변경
					HERO->ActiveUserSellBubble( (LPTSTR)mUserSellName.Cstr(), eCOLOR_GREEN );
				}
				break;
			case ERROR_ITEM_STALL_SELL_RENAME_FAIL:
				{
					/// 변경 실패
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2516 ) );
				}
				break;
			}

			if( userSell )
				userSell->NetUnLock( eLOCK_RENAME );
		}
		break;
	case NM_ITEM_STALL_SELL_RENAME_SYN:
		{
			/// 다른 유저의 노점명 변경됨
			MSG_SYN_ITEM_STALL_SELL_RENAME* msgData = (MSG_SYN_ITEM_STALL_SELL_RENAME*)msg;

			cPlayer* p = OBJECTMAN->GetPlayer( msgData->characterIdx );
			if( p )
			{
				if( p->GetState() == eOBJECT_STATE_STOP && p->GetStopFlag() == eSTOP_OPENSTALL )
				{
					p->ActiveUserSellBubble( msgData->title, eCOLOR_GREEN );

					/// 현재 보고있는 상점의 이름이 변경되었으면 재 세팅
					if( msgData->characterIdx == mUserSellTarget )
					{
						cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
						if( userSell )
							userSell->SetName( msgData->title );
					}
				}
				else
				{
					assert(0);
				}
			}
		}
		break;
	case NM_ITEM_STALL_SELL_CLOSE_RES:
		{
			/// 노점닫기 요청
			MSG_RES_ITEM_STALL_SELL_CLOSE* msgData = (MSG_RES_ITEM_STALL_SELL_CLOSE*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_CLOSE_SUCCESS:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2503 ) );

					if( userSell )
						userSell->Hide();

					HERO->DeActiveUserSellBubble();
					HERO->StandUp();
				}
				break;
			case ERROR_ITEM_STALL_SELL_CLOSE_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2504 ) );
				break;
			}

			if( userSell )
				userSell->NetUnLock( eLOCK_END );
		}
		break;
	case NM_ITEM_STALL_SELL_CLOSE_SYN:	
		{
			/// 다른유저의 노점상 닫힘
			MSG_SYN_ITEM_STALL_SELL_CLOSE* msgData = (MSG_SYN_ITEM_STALL_SELL_CLOSE*)msg;

			cPlayer* p = OBJECTMAN->GetPlayer( msgData->characterIdx );
			if( p )
			{
				/// 상태 체크
				if( p->GetState() != eOBJECT_STATE_STOP )
				{
					assert(0);
					return;
				}
				if( p->GetStopFlag() != eSTOP_OPENSTALL )
				{
					assert(0);
					return;
				}

				p->SetStopFlag( eSTOP_NONE );
				p->DeActiveUserSellBubble();
				p->StandUp();

				/// hero가 이용중인경우,
				if( msgData->characterIdx == GetUserSellTarget() )
				{
					ITEMMAN->ClearUserSellTarget();
					HERO->SetStopFlag( eSTOP_NONE );
					HERO->SetState( eOBJECT_STATE_IDLE );

					cUserSellWindow* usersell = GAMEUI->GetUserSellWindow();
					if( usersell )
						usersell->Hide();
				}
			}
		}
		break;
	case NM_ITEM_STALL_SELL_ADD_RES:
		{
			/// 노점 아이템 등록
			MSG_RES_ITEM_STALL_SELL_ADD* msgData = (MSG_RES_ITEM_STALL_SELL_ADD*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_ADD_SUCCESS:
				if( mTry == ITEM_TRY_SELLITEMADD )
				{
					/// 아이템 등록 성공
					if( userSell && userSell->AddSellItem( mSlotIndex0, mPrice ) == false )
					{
						assert(0);
					}
				}
				break;
			case ERROR_ITEM_STALL_SELL_ADD_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2506 ) );
				break;
			}

			UnlockItemTry( ITEM_TRY_SELLITEMADD );

			if( userSell )
				userSell->NetUnLock( eLOCK_ADD );
		}
		break;
	case NM_ITEM_STALL_SELL_ADD_SYN:
		{
			/// 상대 노점상의 아이템 추가됨
			MSG_SYN_ITEM_STALL_SELL_DAT* msgData = (MSG_SYN_ITEM_STALL_SELL_DAT*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			///
			sStallSellData data;
			data.status = StallSellItemStart;
			data.inventory = msgData->inventory;
			data.price = msgData->price;

			if( userSell && userSell->AddJoinItem( &data ) == false )
			{
				assert(0);
			}
		}
		break;
	case NM_ITEM_STALL_SELL_DEL_RES:
		{
			/// 노점 아이템 삭제
			MSG_RES_ITEM_STALL_SELL_DEL* msgData = (MSG_RES_ITEM_STALL_SELL_DEL*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_DEL_SUCCESS:
				if( mTry == ITEM_TRY_SELLITEMDELETE )
				{
					/// mSlotIndex0 : 노점 슬롯을 사용한다
					if( userSell && userSell->DelSellItem( mSlotIndex0 ) == false )
					{
						assert(0);
					}
				}
				break;
			case ERROR_ITEM_STALL_SELL_DEL_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2507 ) );
				break;
			}

			UnlockItemTry( ITEM_TRY_SELLITEMDELETE );

			if( userSell )
				userSell->NetUnLock( eLOCK_DELETE );
		}
		break;
	case NM_ITEM_STALL_SELL_DEL_SYN:
		{
			MSG_SYN_ITEM_STALL_SELL_DAT* msgData = (MSG_SYN_ITEM_STALL_SELL_DAT*)msg;

			sInventory* inv = &msgData->inventory;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( userSell )
				userSell->DelJoinItem( inv );
		}
		break;
	case NM_ITEM_STALL_SELL_MOD_RES:
		{
			/// 노점아이템 정보 변경 요청
			MSG_RES_ITEM_STALL_SELL_MOD* msgData = (MSG_RES_ITEM_STALL_SELL_MOD*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_MOD_SUCCESS:
				{
					/// 변경 윈도우 띄우기
					GAMEUI->ShowMoneyModifyWindow( eMONEY_NONE, eMBEVENT_USERSELL_ITEMMONEYMODIFY );
				}
				break;
			case ERROR_ITEM_STALL_SELL_MOD_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2508 ) );
				break;
			}

			cUIWindow* sell = (cUIWindow*)GAMEUI->GetUserSellWindow();
			if( sell )
				sell->NetUnLock( eLOCK_ITEMUPDATE );
		}
		break;
	case NM_ITEM_STALL_SELL_MOD_SYN:
		{
			/// 노점 아이템 정보 수정중임
			MSG_SYN_ITEM_STALL_SELL_DAT* msgData = (MSG_SYN_ITEM_STALL_SELL_DAT*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( userSell )
				userSell->PauseJoinItem( &msgData->inventory );
		}
		break;
	case NM_ITEM_STALL_SELL_COM_RES:
		{
			/// 아이템 구입됨
			MSG_RES_ITEM_STALL_SELL_COM* msgData = (MSG_RES_ITEM_STALL_SELL_COM*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			sInventory* inv = &msgData->inventory;

			cItem& item = mItemArray[inv->number];
			int sellCount = item.mCount - inv->count; /// 팔린갯수
			if( item.mDefine )
			{
				/// 판매정보 출력
				cStringT str;
				str.Format( GAMERESOURCEMAN->GetGameText( 248 ), msgData->characterName, item.mDefine->GetName(), sellCount );
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, (LPCTSTR)str.Cstr() );
			}
			else
			{
				assert(0);
			}

			/// 판매자 목록에서 삭제
			if( inv->count == 0 )
			{
				if( userSell )
					userSell->DelSellItem( inv->number );

				/// 인벤토리 삭제	
				NetDumpItem( inv->number );
			}
			else
			{	
				/// 자기 목록 개수 갱신
				if( userSell )
					userSell->ModSellItem( inv->number, inv->count );

				// 갱신후 갯수 초기화
				item.SetCount( inv->count );

				/// 아이템관련 정보 갱신
				UpdateItem();
			}	
		}
		break;
	case NM_ITEM_STALL_SELL_JOIN_RES:
		{
			/// 상대방의 노점상 보기
			MSG_RES_ITEM_STALL_SELL_JOIN* msgData = (MSG_RES_ITEM_STALL_SELL_JOIN*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_JOIN_SUCCESS:
				{
					/// 참여 상태로 변경
					if( userSell )
					{
						userSell->SetStatus( eUSERSELL_JOIN );
						userSell->SetName( msgData->title );
						userSell->SetTargetIndex( mUserSellTarget );
					}

					/// 노점상 정보 세팅
					sStallSellData* data = msgData->stallSellData;
					for( int i = 0; i < msgData->rowCount; ++i, ++data )
					{
						if( userSell && userSell->AddJoinItem( data ) == false )
						{
							assert(0);
							continue;
						}
					}

					HERO->SetStopFlag( eSTOP_USESTALL );

					if( userSell )
						userSell->ShowTop();
				}
				break;
			case ERROR_ITEM_STALL_SELL_JOIN_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2510 ) );
				break;
			case ERROR_ITEM_STALL_SELL_JOIN_OVER:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2511 ) );
				break;
			}
		}
		break;
	case NM_ITEM_STALL_SELL_LEAVE_RES:
		{
			/// 닫기
			MSG_RES_ITEM_STALL_SELL_LEAVE* msgData = (MSG_RES_ITEM_STALL_SELL_LEAVE*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_LEAVE_SUCCESS:
				break;
			case ERROR_ITEM_STALL_SELL_LEAVE_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2504 ) );
				break;
			case ERROR_ITEM_STALL_SELL_LEAVE_CLOSED:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2512 ) );
				break;
			}

			if( userSell )
				userSell->Hide();

			/// 보고잇는 노점 정보 초기화
			mUserSellTarget = 0;

			HERO->SetStopFlag( eSTOP_NONE );
			HERO->SetState( eOBJECT_STATE_IDLE );

			if( userSell )
				userSell->NetUnLock( eLOCK_JOINEND );
		}
		break;
	case NM_ITEM_STALL_SELL_GET_RES:	// 구입결과
		{
			MSG_RES_ITEM_STALL_SELL_GET* msgData = (MSG_RES_ITEM_STALL_SELL_GET*)msg;

			cUserSellWindow* userSell = GAMEUI->GetUserSellWindow();
			if( !userSell )
			{
				assert(0);
			}

			/// 
			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_GET_SUCCESS:
				{
					/// 구입 아이템관련 정보 갱신
					NetSetItem( &msgData->Inventory );
					UpdateItem();
				}
				break;
			case ERROR_ITEM_STALL_SELL_GET_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2513 ) );
				break;
			}

			UnlockItemTry( ITEM_TRY_SELLGET );

			if( userSell )
				userSell->NetUnLock( eLOCK_GET );
		}
		break;
	case NM_ITEM_PUT_CARD_INVENTORY_RES:	/// 아이템에 카드 장착 처리
		{
			MSG_RES_ITEM_PUT_CARD_INVENTORY* msgData = (MSG_RES_ITEM_PUT_CARD_INVENTORY*)msg;

			cPutCardWindow* putCard = GAMEUI->GetPutCardWindow();
			if( !putCard )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_PUT_CARD_INVENTORY_SUCCESS:
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, GAMERESOURCEMAN->GetGameText( 2603 ) );

					/// 삽입한 카드 삭제
					if( mTry == ITEM_TRY_PUTCARD )
						NetDumpItem( mSlotIndex0 );

					sInventory& inv = msgData->Inventory;

					/// 해당 아이템 정보 갱신
					unsigned int slot = inv.number;
					cItem& item = mItemArray[slot];

					/// 장착 카드정보 세팅
					item.mCardIndex1 = inv.cardSlot1;
					item.mCardIndex2 = inv.cardSlot2;
					item.mCardIndex3 = inv.cardSlot3;
					item.mCardIndex4 = inv.cardSlot4;
					item.mCardIndex5 = inv.cardSlot5;

					/// 장착 정보 갱신
					if( putCard )
						putCard->AddCard( msgData->Inventory );

				}
				break;
			case ERROR_ITEM_PUT_CARD_INVENTORY_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, GAMERESOURCEMAN->GetGameText( 2604 ) );
				break;
			case ERROR_ITEM_PUT_CARD_INVENTORY_NOTYET:
				CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, GAMERESOURCEMAN->GetGameText( 2605 ) );
				break;
			}

			UnlockItemTry( ITEM_TRY_PUTCARD );

			if( putCard )
				putCard->NetUnLock();
		}
		break;
	case NM_ITEM_CHANGE_INVENTORY_RES:		/// 아이템 체인지 
		{
			MSG_RES_ITEM_CHANGE_INVENTORY* msgData = (MSG_RES_ITEM_CHANGE_INVENTORY*)msg;

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_CHANGE_INVENTORY_SUCCESS:
				NetTryItem( NM_ITEM_CHANGE_INVENTORY_RES, msgData );
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 243 ));
				break;
			case ERROR_ITEM_CHANGE_INVENTORY_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 244 ));
				break;
			case ERROR_ITEM_CHANGE_INVENTORY_NOTYET:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 223 ));
				break;
			}

			UnlockItemTry( ITEM_TRY_CHANGE );
		}
		break;
	case NM_ITEM_STALL_SELL_SEARCH_RES:
		{
			/// 아이템 검색 결과
			MSG_RES_ITEM_STALL_SELL_SEARCH* msgData = (MSG_RES_ITEM_STALL_SELL_SEARCH*)msg;

			cUserSellSearchWindow* search = GAMEUI->GetUserSellSearchWindow();
			if( !search )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_STALL_SELL_SEARCH_SUCCESS:
				{
					if( search )
					{
						search->Clear();

						for( long i = 0; i < msgData->rowCount; ++i )
						{
							search->AddItem( msgData->table[i].idx, 
								msgData->table[i].characterName, msgData->table[i].price,
								msgData->table[i].mapNumber, msgData->table[i].xPos, msgData->table[i].yPos );
						}

					}
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2520 ) );
				}
				break;
			case ERROR_ITEM_STALL_SELL_SEARCH_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2521 ) );
				break;
			case ERROR_ITEM_STALL_SELL_SEARCH_NOTYET:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2522 ) );
				break;
			}

			if( search )
				search->NetUnLock();
		}
		break;
	case NM_ITEM_COLLECT_RES:
		{
			MSG_RES_ITEM_COLLECT* msgData = (MSG_RES_ITEM_COLLECT*)msg;

			cCardBookWindow* cardbook = (cCardBookWindow*)GAMEUI->GetCardBookWindow();
			if( !cardbook )
			{
				assert(0);
			}

			switch( msgData->ErrorCode )
			{
			case ERROR_ITEM_COLLECT_SUCCESS:
				if( mTry == ITEM_TRY_CARDBOOKADD )
				{
					cItem& item0 = mItemArray[mSlotIndex0];
					cItem& item1 = mItemArray[mSlotIndex1];

					/// 이동
					item1 = item0;
					item0 = 0;

					/// 정보 업데이트
					UpdateItem();
					if( cardbook )
					{
						cTarotSheetWindow* sheet = cardbook->GetTarotSheet();
						if( sheet )
						{
							int i = mSlotIndex1 - INVENTORY_TAROT_BEGIN;
							if( i >= 0 )
								sheet->UpdateData( i );
						}
					}

					ChangeSelectSlot( mSlotIndex0 );
					ChangeSelectSlot( mSlotIndex1 );
				}
				break;
			case ERROR_ITEM_COLLECT_FAIL:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 342 ) );
				break;
			case ERROR_ITEM_COLLECT_NOTYET:
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 342 ) );
				break;
			}

			UnlockItemTry( ITEM_TRY_CARDBOOKADD );
		}
		break;
	case NM_ITEM_MAKESKILL_RES:
	case NM_ITEM_RECIPE_RES:
		{
			/// 조합 전문기술 아이템 & 레시피 아이템
			MSG_RES_MAKESKILL_ITEM* msgData = (MSG_RES_MAKESKILL_ITEM*)msg;
			NetMixSkillItem( msgData );
		}
		break;
	case NM_ITEM_MIXED_RES:
		{
			/// 조합 아이템 결과
			MSG_RES_ITEM_MIXED* msgData = (MSG_RES_ITEM_MIXED*)msg;
			NetMixItem( msgData );
		}
		break;
	default:
		assert( 0 && "invalid network message" );
	}
}

void cItemManager::NetSetItem( sInventory* inv, bool setCool )
{
	unsigned short slotIndex = inv->number;

	if( slotIndex > MAX_INVENTORY )
	{
		assert( 0 && "index out of range" );
		return;
	}

	cItem& item = mItemArray[slotIndex];

	if( item.mCount > 0 )
	{
		if(item.mDBIndex != inv->idx || item.mIndex != inv->ItemIndex )
		{
			assert( 0 && "item already exist" );
			return;
		}
	}

	cItemDefine* itemDefine = GetItemDefine( inv->ItemIndex );

	if( itemDefine == 0 )
	{
		assert( 0 && "failed to find item define" );
		return;
	}

	item.mDBIndex = inv->idx;
	item.mIndex = inv->ItemIndex;
	item.mCount = inv->count;
	item.mSeal = (inv->seal != 0);
	item.mDefine = itemDefine;
	item.mEnhanced = inv->enhanced;
	item.mEquipType = itemDefine->mEquipType;
	item.mFlag = itemDefine->mFlag;
	item.mCardIndex1 = inv->cardSlot1;
	item.mCardIndex2 = inv->cardSlot2;
	item.mCardIndex3 = inv->cardSlot3;
	item.mCardIndex4 = inv->cardSlot4;
	item.mCardIndex5 = inv->cardSlot5;

	if( item.mIcon )
		item.BindIcon( item.mIcon );
	
	/// 아이템 세팅, 외부조건에 의한 아이템 사용, 분리, 아이템 획득, 아이템 구입
	/// 쿨타임 복사기능을 해야하면
	if( setCool == true )
		COOLMAN->CopyCoolTime( item.mIndex );

	/// 퀘스트용 아이템이면 이동불가 처리
	eItemIn in = GetItemIn( slotIndex );
	if( in == ITEM_IN_INVEN_QUEST )
		item.SetUsedFlag( false, false );
}


void cItemManager::NetTryItem( unsigned int protocol, void* msg )
{
	switch( mTry )
	{
	case ITEM_TRY_MOVE:
		if( protocol == NM_ITEM_MOV_INVENTORY_RES ||
			protocol == NM_NPC_ITEM_MOV2_INVENTORY_RES )
			NetMoveItem( mSlotIndex0, mSlotIndex1 );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_MERGE:
		if( protocol == NM_ITEM_MERGE_INVENTORY_RES )
		{
			NetMoveItem( mSlotIndex0, mSlotIndex1 );
		}
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_USE:
		if( protocol == NM_ITEM_USE_INVENTORY_RES )
			NetUseItem( mSlotIndex0 );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_EQUIP:
		if( protocol == NM_ITEM_MOV_INVENTORY_RES )
			NetEquipItem( mSlotIndex0 );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_UNEQUIP:
		if( protocol == NM_ITEM_MOV_INVENTORY_RES )
			NetUnEquipItem( mSlotIndex0 );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_DUMP:
		if( protocol == NM_ITEM_DEL_INVENTORY_RES )
			NetDumpItem( mSlotIndex0 );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_SPLIT:
		if( protocol == NM_ITEM_DIVIDE_INVENTORY_RES ||
			protocol == NM_ITEM_MOV_INVENTORY_RES )
			NetSplitItem( (MSG_RES_ITEM_DIVIDE_INVENTORY*)msg );
		else if( protocol == NM_NPC_ITEM_MOV2_INVENTORY_RES )
			NetSplitItem( (MSG_RES_NPC_ITEM_MOV2_INVENTORY*)msg, mSlotIndex0, mSlotIndex1 );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_BUY:
		if( protocol == NM_NPC_ITEM_BUY_RES )
			NetBuyItem( (MSG_RES_NPC_ITEM_BUY*)msg );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_SELL:
		if( protocol == NM_NPC_ITEM_SELL_RES )
			NetSellItem( (MSG_RES_NPC_ITEM_SELL*)msg );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_GET:
		if( protocol == NM_ITEM_GET_RES )
			NetGetItem( (MSG_RES_ITEM_GET*)msg );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_DISJOINT:
		if( protocol == NM_ITEM_DISJOINT_INVENTORY_RES )
			NetDisjointItem( (MSG_RES_ITEM_DISJOINT_INVENTORY*)msg );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_ENHANCEDEND:
		if( protocol == NM_ITEM_ENHANCED_END_RES )
			NetEnhancedItem( (MSG_RES_ITEM_ENHANCED_END*)msg );
		else
			assert( 0 && "invalid protocol" );
		break;

		/// 퀘스트 - 아이템 보상 & 반납
	case ITEM_TRY_QUEST_REWARDTAKE:
		if( protocol == NM_ITEM_REWARD_RES )
			NetRewardItem( (MSG_RES_ITEM_REWARD*)msg );
		else if( protocol == NM_ITEM_TAKE_RES )
			NetTakeItem( (MSG_RES_ITEM_TAKE*)msg );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_QUEST_ADDBYITEM:
		if( protocol == NM_ITEM_REWARD_RES )
			NetRewardItem( (MSG_RES_ITEM_REWARD*)msg );
		else
			assert( 0 && "invalid protocol" );
		break;

		/// 퀘스트 - 아이템 반납
	case ITEM_TRY_QUEST_TAKE:
		if( protocol == NM_ITEM_TAKE_RES )
			NetTakeItem( (MSG_RES_ITEM_TAKE*)msg );
		else
			assert( 0 && "invalid protocol" );
		break;

	case ITEM_TRY_CHANGE:
		if( protocol == NM_ITEM_CHANGE_INVENTORY_RES )
			NetChangeItem( (MSG_RES_ITEM_CHANGE_INVENTORY*)msg );
		else
			assert( 0 && "invalid protocol" );
		break;

	default:
		assert( 0 && "invalid item try" );
	}
}

/// 아이템 이동
void cItemManager::NetMoveItem( unsigned int i0, unsigned int i1 )
{
	assert( i0 <= MAX_INVENTORY && "index out of range" );
	assert( i1 <= MAX_INVENTORY && "index out of range" );
	assert( i0 != i1 );

	if( i0 == i1 )
		return;

	/// 이동 가능 여부를 검사
	eItemIn in0 = GetItemIn( i0 );
	eItemIn in1 = GetItemIn( i1 );

	assert( in0 != ITEM_IN_NULL );
	assert( in1 != ITEM_IN_NULL );

	///
	cItem& item0 = mItemArray[i0];
	if( item0.mCount == 0 )
		return;

	cItem& item1 = mItemArray[i1];
	const cItemDefine* itemDefine = item0.mDefine;
	assert( itemDefine );

	/// 장착 -> 인벤 개인
	if( in0 == ITEM_IN_EQUIP && in1 == ITEM_IN_INVEN_PRIVATE )
	{
		if( item1.mCount && (item1.mFlag & mFlagArray[i0] ) != item1.mFlag )
			return;
		if( MoveItemDown( i0, i1 ) == false )
			return;

		/// 아이템관련 정보 갱신
		CheckItemCount();
	}
	/// 인벤 개인 -> 장착
	else if( in0 == ITEM_IN_INVEN_PRIVATE && in1 == ITEM_IN_EQUIP )
	{
		if( item0.mEquipType == ITEM_EQUIP_TWO_HANDS )
		{
			if( i1 == INVENTORY_HAND_LEFT1 )
				i1 = INVENTORY_HAND_RIGHT1;
			else if( i1 == INVENTORY_HAND_LEFT2 )
				i1 = INVENTORY_HAND_RIGHT2;
		}
		if( item0.mCount && (item0.mFlag & mFlagArray[i1] ) != item0.mFlag )
			return;
		if( MoveItemUp( i0, i1 ) == false )
			return;

		/// 아이템관련 정보 갱신
		CheckItemCount();
	}
	/// 인벤 개인 -> 인벤 개인, 인벤 몰 -> 인벤 몰
	else if( (in0 == ITEM_IN_INVEN_PRIVATE || in0 == ITEM_IN_INVEN_MALL) && in0 == in1 )
	{
		unsigned short capacity = itemDefine->mCapacity;
	
		if( item0.mIndex == item1.mIndex )
		{
			/// 같은 종류면 병합
			unsigned short capacity = itemDefine->mCapacity;

			/// 병합이 가능한 갯수면 병합
			if( capacity > 1 && item1.mCount < capacity )
			{
				unsigned short value = item0.mCount;
				unsigned short count = item1.mCount + value;

				if( count > capacity )
				{
					value -= (count - capacity);
					count = capacity;
				}

				assert( value > 0 );
				item0 = item0.mCount - value;
				item1 = count;
			}

			/// 이동, 교환등이 아니므로 컬러를 원상태로 복구한다
			item0.ClearColor();
			item1.ClearColor();
		}
		else
		{
			/// 다른 종류면 교환
			cItem tempItem = item0;
			item0 = item1;
			item1 = tempItem;
		}
	}
	/// 창고 개인 -> 창고 개인, 창고 몰 -> 창고 몰
	else if( (in0 == ITEM_IN_WAREHOUSE_PRIVATE || in0 == ITEM_IN_WAREHOUSE_MALL) && in0 == in1 )
	{
		if( item1.mCount )
			return;

		/// 빈칸으로 이동
		item1 = item0;
		item0 = 0;
	}
	/// 인벤 개인 <-> 창고 개인
	/// 인벤 몰 <-> 창고 몰
	else if( (in0 == ITEM_IN_INVEN_PRIVATE && in1 == ITEM_IN_WAREHOUSE_PRIVATE) ||
		(in0 == ITEM_IN_WAREHOUSE_PRIVATE && in1 == ITEM_IN_INVEN_PRIVATE) ||
		(in0 == ITEM_IN_INVEN_MALL && in1 == ITEM_IN_WAREHOUSE_MALL) ||
		(in0 == ITEM_IN_WAREHOUSE_MALL && in1 == ITEM_IN_INVEN_MALL) )
	{
		if( item1.mCount )
			return;

		/// 빈칸으로 이동
		item1 = item0;
		item0 = 0;

		/// 쿨타임 복사 ( 창고 -> 인벤 )
		/// 그 외엔 전부 쿨타임 취소
		if( in0 == ITEM_IN_WAREHOUSE_PRIVATE && in1 == ITEM_IN_INVEN_PRIVATE )
			COOLMAN->CopyCoolTime( item1.mIndex );
		else
			item1.EndCoolTime();

		///
		if( in1 == ITEM_IN_INVEN_PRIVATE || in1 == ITEM_IN_INVEN_MALL ||
			in1 == ITEM_IN_WAREHOUSE_PRIVATE || in1 == ITEM_IN_WAREHOUSE_MALL )
		{
			/// 아이템관련 정보 갱신
			UpdateItem();
		}
	}
	else
	{
		return;
	}

	/// 아이템 셀을 검사
	CheckItemSlot( i0 );
	CheckItemSlot( i1 );

	ChangeSelectSlot( i0 );
	ChangeSelectSlot( i1 );
}

/// 소모성 아이템 사용 
void cItemManager::NetUseItem( unsigned int i )
{
	cItem& item = mItemArray[i];
	cItemDefine* itemDefine = item.mDefine;
	if( !itemDefine )
	{
		assert(0);
		return;
	}

	unsigned char type = itemDefine->GetType();
	unsigned char subtype = itemDefine->GetSubType();

	/// 소모성 아이템만 사용 
	if( type == ITEM_ETC1 || ( type == ITEM_CARD && subtype == ITEM_CARD_COMMON ) )
	{
		/// 쿨타임매니저에 사용 등록
		cItemAbility* itemAbil = itemDefine->GetAbililty();
		if( itemAbil && itemAbil->GetCoolTime() > 0 )
		{
			COOLMAN->StartCoolTime( item.mIndex );
		}
		
		/// 아이템 사용 
		item.SetCount( item.mCount - 1 );

		/// 아이템관련 정보 갱신
		UpdateItem();

		/// 선택 슬롯 갱신
		ChangeSelectSlot( i );
	}
	else
	{
		assert(0);
	}
}

/// 아이템 장착 
void cItemManager::NetEquipItem( unsigned int i )
{
	assert( i <= MAX_INVENTORY && "index out of range" );

	/// 장착
	cItem& item = mItemArray[i];
	cItemDefine* itemDefine = item.mDefine;
	if( !itemDefine )
	{
		assert(0);
		return;
	}

	unsigned char type = itemDefine->GetType();
	unsigned char subType = itemDefine->GetSubType();
	unsigned int i1 = 0;

	switch( type )
	{
	case ITEM_WEAPON:
		if( EquipWeapon( i1, i, item.mEquipType ) == false )
			return;
		break;
	case ITEM_WEAR:
		if( EquipWear( i1, i, subType ) == false )
			return;
		break;
	case ITEM_ACCESSORY:
		if( EquipAccessory( i1, i, subType ) == false )
			return;
		break;
	case ITEM_CARD:
		if( subType == ITEM_CARD_EQUIP_C )
		{
			i1 = mSlotIndex1;
			if( EquipCard( i1, i ) == false )
				return;
		}
		break;
	default:
		assert( 0 && "invalid item type" );
		return;
	}

	/// 전체 능력치검사
	CheckEquipAbility();

	/// 착용 방어구셋 갱신
	HERO->ResetArmorSets();

	/// 아이템 셀을 검사
	CheckItemSlot( i1 );

	// 선택슬롯 갱신
	ChangeSelectSlot( i );
	ChangeSelectSlot( i1 );

	/// 아이템관련 정보 갱신
	CheckItemCount();
}

/// 아이템 장착 해제
void cItemManager::NetUnEquipItem( unsigned int i )
{
	/// 탈착
	unsigned int i1 = 0;

	if( FindEmptySlot( &i1, INVENTORY_BAG0_BEGIN, INVENTORY_BAG3_END ) == false )
		return;

	/// 해당 아이템 능력치 검사.
	cItem& item0 = mItemArray[i];
	cItem& item1 = mItemArray[i1];

	/// 장착해제
	item1 = item0;
	item0 = 0;

	/// 전체 능력치검사
	CheckEquipAbility();

	/// 착용 방어구셋 갱신
	HERO->ResetArmorSets();

	/// 아이템 셀을 검사
	CheckItemSlot( i );

	// 선택슬롯 갱신
	ChangeSelectSlot( i );
	ChangeSelectSlot( i1 );

	/// 아이템관련 정보 갱신
	CheckItemCount();
}

/// 아이템 버리기 
void cItemManager::NetDumpItem( unsigned int i )
{
	/// 아이템 삭제
	mItemArray[i] = 0;

	/// 아이템 삭제 갯수 갱신
	eItemIn in = GetItemIn(i);
	if( in == ITEM_IN_INVEN_PRIVATE || in == ITEM_IN_INVEN_MALL )
	{
		/// 아이템관련 정보 갱신
		UpdateItem();
	}

	// 선택슬롯 갱신
	ChangeSelectSlot( i );
}

/// 아이템 분리 ( 인벤 -> 인벤)
void cItemManager::NetSplitItem( MSG_RES_ITEM_DIVIDE_INVENTORY* msgData )
{
	sInventory* inv = msgData->Inventory;
	for( unsigned long i = 0; i < msgData->RowCount; i++, inv++ )
	{
		/// 분리대신 새로생겨난 아이템 세팅.(갯수 추가안함)
		NetSetItem( inv );
    }

	/// 아이템이 있으면 그때 검사
	if( msgData->RowCount > 0 )
	{
		/// 아이템관련 정보 갱신
		UpdateItem();
	}
}

/// 아이템 분리  ( 인벤 <-> 창고 )
void cItemManager::NetSplitItem( MSG_RES_NPC_ITEM_MOV2_INVENTORY* msgData, unsigned int slotIndex0, unsigned int slotIndex1 )
{
	int count = 0;

	/// 분리전의 원래 갯수
	cItem& item = mItemArray[slotIndex0];
	count = item.mCount;
	
	eItemIn in0 = GetItemIn( slotIndex0 );
	eItemIn in1 = GetItemIn( slotIndex1 );

	/// 쿨타임 세팅여부 ( 창고 -> 인벤 일때만 한다 )
	bool setcool = false;

	/// 창고 ->인벤
	if( in0 == ITEM_IN_WAREHOUSE_PRIVATE && in1 == ITEM_IN_INVEN_PRIVATE )
	{
		setcool = true;
	}

    sInventory* inv = msgData->Inventory;
	for( unsigned long i = 0; i < msgData->RowCount; i++, inv++ )
	{
		/// 분리대신 새로생겨난 아이템 세팅.(갯수 추가안함)
		NetSetItem( inv, setcool );
	}

	/// 아이템이 있으면 그때 검사
	if( msgData->RowCount > 0 )
	{
		/// 아이템관련 정보 갱신
		UpdateItem();
	}
}

/// 아이템 줍기 - 인벤토리만 세팅 ( 기존에 있는 아이템과 자동 합치기 됨 )
void cItemManager::NetGetItem( MSG_RES_ITEM_GET* msgData )
{
	cStringT str;

	sInventory* inv = msgData->Inventory;
	for ( long i = 0; i < msgData->RowCount; i++, inv++ )
	{
		/// 줍기전의 갯수 확인하기
		cItem& item = mItemArray[inv->number];

		/// 추가된 갯수 구하기
		int addcount = inv->count - item.mCount;
		
		/// 갯수 및 무게 추가 안함
		NetSetItem( inv );
        
		/// 아이템 획득메세지 쏘기 
		cItemDefine* itemDefine = GetItemDefine( item.mIndex );
		if( itemDefine )
		{
			LPCTSTR countStr = cNumberEditBox::FormatNumber( addcount );

			str.Format( GAMERESOURCEMAN->GetGameText( 240 ), countStr );
			CHATMANAGER->AddItemMsg( item.mIndex, inv->number, 0, (LPCTSTR)str.Cstr() );
		}
	}

	/// 갯수 갱신
	if( msgData->RowCount > 0 )
	{
		/// 아이템관련 정보 갱신
		UpdateItem();
	}
}

//ItemActiveFront = left2, right2
//ItemActiveBack = left1, right1
void cItemManager::NetSwitchWeapon( eItemActiveWeapon activeWeapon )
{
	SetSwitchWeapon( activeWeapon );
}

/// 아이템 사기 (새로운 칸에 삽입)
void cItemManager::NetBuyItem( MSG_RES_NPC_ITEM_BUY* msgData )
{
	cStringT str;
	sInventory* inv = msgData->inventory;

	int total = 0;
	unsigned long itemIndex = inv->ItemIndex;
	for ( long i = 0; i < msgData->rowCount; i++, inv++ )
	{
		/// 줍기전의 갯수 확인하기
		cItem& item = mItemArray[inv->number];

		if( inv->count == 0 )
		{
			item.SetCount( 0 );
		}
		else
		{
			unsigned long count = item.mCount;

			/// 아이템 세팅
			NetSetItem( inv );

			if( item.GetDefine() && item.GetDefine()->GetType() != ITEM_COIN )
			{
				/// 새로운 갯수 - 기존갯수 = 실제로 추가된 개수
				total += ( inv->count - count );
			}

			ChangeSelectSlot( inv->number );
		}
	}

	/// 아이템관련 정보 갱신
	if( msgData->rowCount > 0 )
	{
		UpdateItem();

		/// 아이템 획득메세지 쏘기 
		if( total > 0 )
		{
			cItemDefine* itemDefine = GetItemDefine( itemIndex );
			if( itemDefine )
			{
				LPCTSTR countStr = cNumberEditBox::FormatNumber( total );

				str.Format( GAMERESOURCEMAN->GetGameText( 209 ), itemDefine->GetName(), countStr );
				CHATMANAGER->AddSystemMsg( eSYSTEM_NPCSTORE, (LPCTSTR)str.Cstr() );
			}
		}
		else
		{
			assert(0);
		}
	}
}

/// 아이템 팔기
void cItemManager::NetSellItem( MSG_RES_NPC_ITEM_SELL* msgData )
{
	cStringT str;
	sInventory* inv = msgData->inventory;

	unsigned long itemIndex = inv->ItemIndex;
	for ( long i = 0; i < msgData->rowCount; i++, inv++ )
	{
		/// 팔기전의 갯수 확인하기
		cItem& item = mItemArray[inv->number];

		/// 완전 삭제
		if( inv->count == 0 )
		{
			item.SetCount( 0 );
		}
		else
		{
			/// 아이템 세팅
			NetSetItem( inv );
		}
	}

	/// 아이템관련 정보 갱신
	UpdateItem();
	ChangeSelectSlot( mSlotIndex0 );
}

/// 아이템 분해
void cItemManager::NetDisjointItem( MSG_RES_ITEM_DISJOINT_INVENTORY* msgData )
{
	cNpcDisjointWindow* p = GAMEUI->GetNpcDisjointWindow();
	if( p )
	{
		/// 분해된 아이템 삭제
		unsigned int slotIdx = p->GetSlotIndex();
		NetDumpItem( slotIdx );
	}
	else
	{
		assert(0);
	}

	///
	cStringT str;
	sInventory* inv = msgData->Inventory;
	for ( unsigned long i = 0; i < msgData->RowCount; i++, inv++ )
	{
		/// 새로운 갯수 - 기존갯수 = 실제로 추가된 개수
		cItem& item = mItemArray[inv->number];

		/// 추가된 갯수 구하기
		int addcount = inv->count - item.mCount;

		/// 아이템 세팅
		NetSetItem( inv );

		/// 아이템 획득메세지 쏘기 
		cItemDefine* itemDefine = GetItemDefine( inv->ItemIndex );
		if( itemDefine )
		{
			LPCTSTR countStr = cNumberEditBox::FormatNumber( addcount );

			str.Format( GAMERESOURCEMAN->GetGameText( 253 ), itemDefine->GetName(), countStr );
			CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, (LPCTSTR)str.Cstr() );
		}
	}

	if( msgData->RowCount > 0 )
	{
		/// 아이템관련 정보 갱신
		UpdateItem();
	}
}

void cItemManager::NetEnhancedItem( MSG_RES_ITEM_ENHANCED_END* msgData )
{
	cEnhancedWindow* win = GAMEUI->GetEnhancedWindow();

	bool success = false;
	cStringT str;
	sInventory* inv0 = &msgData->Inventory[0];		/// 강화 아이템
	sInventory* inv1 = &msgData->Inventory[1];		/// 강화 카드

	/// 강화아이템 검사
	cItem& item = mItemArray[inv0->number];

	if( inv0->count > 0 )
	{
		item.mCardIndex1 = inv0->cardSlot1;
		item.mCardIndex2 = inv0->cardSlot2;
		item.mCardIndex3 = inv0->cardSlot3;
		item.mCardIndex4 = inv0->cardSlot4;
		item.mCardIndex5 = inv0->cardSlot5;

		if( item.mEnhanced < inv0->enhanced )
		{
			/// 강화성공
			item.mEnhanced = inv0->enhanced;
			success = true;
			
			CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, GAMERESOURCEMAN->GetGameText( 256 ) );
		}
		else if( item.mEnhanced == inv0->enhanced )
		{
			/// 강화실패 - 변동없음
			CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, GAMERESOURCEMAN->GetGameText( 257 ) );
		}
		else if( item.mEnhanced > inv0->enhanced )
		{
			/// 강화실패 - 단계 하강
			item.mEnhanced = inv0->enhanced;

			CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, GAMERESOURCEMAN->GetGameText( 257 ) );
			CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, GAMERESOURCEMAN->GetGameText( 258 ) );
		}

		if( win )
			win->Clear( false );
	}
	else
	{
		/// 강화실패 - 아이템 파괴
		NetDumpItem( inv0->number );

		CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, GAMERESOURCEMAN->GetGameText( 257 ) );
		CHATMANAGER->AddSystemMsg( eSYSTEM_DOITEM, GAMERESOURCEMAN->GetGameText( 259 ) );

		/// 파괴시 전체 클리어
		if( win )
			win->Clear( true );
	}

	/// 윈도우에 등록된 아이템 클리어 및 결과 세팅
	if( win )
		win->SetResult( success );

	NiTransform trans;
	trans.MakeIdentity();
	trans.m_Translate = NiPoint3( 0.0f, 0.0f, 0.0f );

	if( success == true )
	{
		HERO->SetLinkdEffect( eLINK_FOOT, "./Data/Effect/eff_enhance_s.nif", &trans, false, false );
		HERO->ChangeAnimation( (ePLAYER_ANIMATIONTYPE) 817 );
	}
	else
	{
		HERO->SetLinkdEffect( eLINK_BODY, "./Data/Effect/eff_enhance_f.nif", &trans, false, false );
		HERO->ChangeAnimation( (ePLAYER_ANIMATIONTYPE) 818 );
	}

	/// 강화카드 삭제
	NetDumpItem( inv1->number );

	/// 아이템 관련 정보 갱신
	UpdateItem();
}

void cItemManager::DeleteQuestInsertItem()
{
	/// 의뢰아이템 삭제
	if( mTry == ITEM_TRY_QUEST_ADDBYITEM )
	{
		if( mSlotIndex0 <= MAX_INVENTORY )
		{
			cItem& item = mItemArray[mSlotIndex0];
			cItemDefine* itemDefine = item.mDefine;
			if( itemDefine )
			{
				unsigned char type = itemDefine->GetType();
				unsigned char subtype = itemDefine->GetSubType();

				/// 소모성 아이템만 사용 
				if( type == ITEM_ETC1 || ( type == ITEM_CARD && subtype == ITEM_CARD_COMMON ) )
				{
					/// 쿨타임매니저에 사용 등록
					cItemAbility* itemAbil = itemDefine->GetAbililty();
					if( itemAbil && itemAbil->GetCoolTime() > 0 )
						COOLMAN->StartCoolTime( item.mIndex );

					/// 아이템 사용 
					item.SetCount( item.mCount - 1 );

					/// 아이템관련 정보 갱신
					UpdateItem();

					/// 선택 슬롯 갱신
					ChangeSelectSlot( mSlotIndex0 );
				}
			}
			else
			{
				assert(0);
			}
		}
	}
}

/// 퀘스트 - 아이템 보상, 신규퀘스트 아이템 제공
void cItemManager::NetRewardItem( MSG_RES_ITEM_REWARD* msgData )
{
	cStringT str;

	sInventory* inv = msgData->inventory;
	for ( long i = 0; i < msgData->rowCount; i++, inv++ )
	{
		/// 퀘스트 보상으로 아이템 획득 
		cItem& item = mItemArray[inv->number];

		/// 추가된 갯수 구하기
		int addcount = inv->count - item.mCount;

		/// 갯수 및 무게 추가 안함
		NetSetItem( inv );

		/// 아이템 획득메세지 쏘기 
		cItemDefine* itemDefine = GetItemDefine( item.mIndex );
		if( itemDefine )
		{
			LPCTSTR countStr = cNumberEditBox::FormatNumber( addcount );

			str.Format( GAMERESOURCEMAN->GetGameText( 240 ), countStr );
			CHATMANAGER->AddItemMsg( item.mIndex, inv->number, GAMERESOURCEMAN->GetGameText( 236 ), (LPCTSTR)str.Cstr(), true );
		}
	}

	/// 갯수 갱신
	if( msgData->rowCount > 0 )
	{
		/// 아이템관련 정보 갱신
		UpdateItem();
	}
}

/// 퀘스트 - 아이템 반납
void cItemManager::NetTakeItem( MSG_RES_ITEM_TAKE* msgData )
{
	sInventory* inv = msgData->inventory;
	for( long i = 0; i < msgData->rowCount; ++i, ++inv )
	{
		cItem& item = mItemArray[inv->number];
		item.SetCount( inv->count );

		// 선택슬롯 갱신
		if( inv->count == 0 )
			ChangeSelectSlot( inv->number );
	}
	
	/// 갯수 갱신
	if( msgData->rowCount > 0 )
	{
		/// 아이템관련 정보 갱신
		UpdateItem();
	}
}

/// 
void cItemManager::NetTradeItem( MSG_RES_ITEM_EXCHANGE_END* msgData )
{
	/// 거래된 아이템 삭제
	cTradeWindow* trade = GAMEUI->GetTradeWindow();
	if( !trade )
	{
		assert(0);
		return;
	}

	/// 삭제
	int lastSlot = trade->GetMyLastSlot();
	sTradeItem* tradeItem = trade->GetMyItem();
	for( int i = 0; i < lastSlot; ++i, ++tradeItem )
	{
		NetDumpItem( tradeItem->mSlotIndex );
	}

	cStringT str;

	sInventory* inv = msgData->Inventory;
	for ( unsigned long i = 0; i < msgData->RowCount; i++, inv++ )
	{
		/// 갯수 및 무게 추가 안함
		NetSetItem( inv );

		/// 아이템 획득메세지 쏘기 
		cItemDefine* itemDefine = GetItemDefine( inv->ItemIndex );
		if( itemDefine )
		{
			LPCTSTR countStr = cNumberEditBox::FormatNumber( inv->count );

			str.Format( GAMERESOURCEMAN->GetGameText( 240 ), countStr );
			CHATMANAGER->AddItemMsg( inv->ItemIndex, inv->number, 0, (LPCTSTR)str.Cstr() );
		}
	}

	/// 갯수 갱신
	if( msgData->RowCount > 0 )
	{
		/// 아이템관련 정보 갱신
		UpdateItem();
	}
}

void cItemManager::NetChangeItem( MSG_RES_ITEM_CHANGE_INVENTORY* msgData )
{
	/// 체인지 한 아이템 삭제
	NetDumpItem( mSlotIndex0 );
	
	///
	cStringT str;
	sInventory* inv = msgData->Inventory;
	for ( unsigned long i = 0; i < msgData->RowCount; i++, inv++ )
	{
		/// 새로운 갯수 - 기존갯수 = 실제로 추가된 개수
		cItem& item = mItemArray[inv->number];

		/// 추가된 갯수 구하기
		int addcount = inv->count - item.mCount;

		/// 아이템 세팅
		NetSetItem( inv );

		/// 아이템 획득메세지 쏘기 
		cItemDefine* itemDefine = GetItemDefine( inv->ItemIndex );
		if( itemDefine )
		{
			LPCTSTR countStr = cNumberEditBox::FormatNumber( addcount );

			str.Format( GAMERESOURCEMAN->GetGameText( 240 ), countStr );
			CHATMANAGER->AddItemMsg( item.mIndex, inv->number, 0, (LPCTSTR)str.Cstr() );
		}
	}

	if( msgData->RowCount > 0 )
	{
		/// 아이템관련 정보 갱신
		UpdateItem();
	}
}

void cItemManager::DeleteMixInsertItem()
{
	if( mTry == ITEM_TRY_MIXSKILL )
	{
		if( mSlotIndex0 <= MAX_INVENTORY )
		{
			cItem& item = mItemArray[mSlotIndex0];
			item.SetCount( item.mCount - 1 );

			/// 갯수 갱신
			UpdateItem();

			/// 선택 슬롯 갱신
			ChangeSelectSlot( mSlotIndex0 );
		}
	}
	else
	{
		assert(0);
	}
}

void cItemManager::NetMixSkillItem( MSG_RES_MAKESKILL_ITEM* msgData )
{
	sInventory* inv = &msgData->inventory;
	NetSetItem( inv );

	/// 갯수 갱신
	UpdateItem();

	/// 선택 슬롯 갱신
	ChangeSelectSlot( inv->number );
}

void cItemManager::NetMixItem( MSG_RES_ITEM_MIXED* msgData )
{
	cStringT str;
	sInventory* inv = msgData->inventory;
	for ( long i = 0; i < msgData->rowCount; i++, inv++ )
	{
		/// 새로운 갯수 - 기존갯수 = 실제로 추가된 개수
		cItem& item = mItemArray[inv->number];

		if( inv->count == 0 )
			item.SetCount( 0 );

		int addcount = inv->count - item.mCount;

		if( addcount != 0 )
			NetSetItem( inv );

		if( addcount > 0 )
		{
			/// 아이템 획득메세지 쏘기 
			cItemDefine* itemDefine = GetItemDefine( inv->ItemIndex );
			if( itemDefine )
			{
				LPCTSTR countStr = cNumberEditBox::FormatNumber( addcount );

				str.Format( GAMERESOURCEMAN->GetGameText( 240 ), countStr );
				CHATMANAGER->AddItemMsg( item.mIndex, inv->number, 0, (LPCTSTR)str.Cstr() );
			}
		}

		/// 선택 슬롯 갱신
		ChangeSelectSlot( inv->number );
	}

	/// 갯수 갱신
	UpdateItem();
}

bool cItemManager::CheatMakeItem( sInventory* inv )
{
	if( IsLocked() )
		return false;

	int total = 0;
	unsigned long itemIndex = inv->ItemIndex;
	{
		/// 줍기전의 갯수 확인하기
		cItem& item = mItemArray[inv->number];

		/// 새로운 갯수 - 기존갯수 = 실제로 추가된 개수
		total += ( inv->count - item.mCount );

		/// 아이템 세팅
		NetSetItem( inv );
	}

	/// 아이템관련 정보 갱신
	UpdateItem();

	/// 아이템 획득메세지 쏘기
	cItemDefine* itemDefine = GetItemDefine( itemIndex );
	if( itemDefine )
	{
		LPCTSTR countStr = cNumberEditBox::FormatNumber( total );

		cStringT str;
		str.Format( GAMERESOURCEMAN->GetGameText( 215 ), itemDefine->GetName(), countStr );
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, (LPCTSTR)str.Cstr() );
	}

	return true;
}
