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

#include "UIText.h"
#include "Gauge.h"

#include "GameUIManager.h"
#include "DragWindow.h"
#include "QuickManager.h"
#include "CoolTimeManager.h"
#include "GameUIManager.h"
#include "UIMsgboxEvent.h"
#include "LootingWindow.h"
#include "HeroInfoWindow.h"
#include "UserSellWindow.h"
#include "CardBookWindow.h"
#include "TarotSheetWindow.h"
#include "InventoryWindow.h"
#include "BagWindow.h"
#include "WareHouseWindow.h"
#include "EnhancedWindow.h"

#include "ObjectManager.h"
#include "hero.h"

#include "SceneManager.h"
#include "DropItemSceneNode.h"
#include "ChatManager.h"
#include "GameResourceManager.h"
#include "FontAgent.h"
#include "Application.h"
#include "Npc_Common.h"
#include "ItemMixManager.h"
#include "ItemMixWindow.h"

#define ITEM_TEXT_FILENAME			"./Script/Language/Item_Name.txt"
#define ITEM_FILENAME_FILENAME		"./Script/Resource/Item_FileName.txt"
#define ITEM_DEFINE_FILENAME		"./Script/Resource/Item_Define.txt"
#define ITEM_ABILITY_FILENAME		"./Script/Resource/Item_Ability.txt"
#define ITEM_LIMIT_FILENAME			"./Script/Resource/Item_Limit.txt"
#define ITEM_CARD_FILENAME			"./Script/Resource/Item_Card.txt"
#define ITEM_TAROT_FILENAME			"./Script/Resource/Item_Tarot.txt"
#define ITEM_SPREAD_FILENAME		"./Script/Resource/Item_Spread.txt"
#define ITEM_NPCSTORE_FILENAME		"./Script/Resource/Item_NpcStore.txt"
#define ITEM_DISJOINT_FILENAME		"./Script/Resource/Item_Disjoint.txt"
#define ITEM_ENHANCED_FILENAME		"./Script/Resource/Item_Enhanced.txt"
#define ITEM_CARDSLOT_FILENAME		"./Script/Resource/Item_Card_Slot.txt"
#define ITEM_CATEGORY_FILENAME		"./Script/Resource/Item_CategoryTable.txt"

cItemManager* cItemManager::mSingleton = 0;

cItemManager::cItemManager()
: mDropItemMap( 200 )
, mLocked( false )
, mWeightGauge( 0 )
, mMaxWeight( 0.0f )
, mCurWeight( 0.0f )
, mLinkedIcon( 0 )
, mTradeTarget(0)
, mTradeMoney(0)
, mUserSellTarget(0)
, mLastAccutime(0)
{
	assert( mSingleton == 0 && "bad singleton!" );
	mSingleton = this;

	mItemText = 0;

	/// 플랙 배열 초기화
	mFlagArray[INVENTORY_WEAR_HAT] = ITEM_FLAG_HEAD;
	mFlagArray[INVENTORY_WEAR_BODY1] = ITEM_FLAG_UPPER;
	mFlagArray[INVENTORY_WEAR_BODY2] = ITEM_FLAG_LOWER;
	mFlagArray[INVENTORY_WEAR_HAND] = ITEM_FLAG_HANDS;
	mFlagArray[INVENTORY_WEAR_FOOT] = ITEM_FLAG_FEET;

	mFlagArray[INVENTORY_WEAR_EARRING] = ITEM_FLAG_EARRING;
	mFlagArray[INVENTORY_WEAR_NECKLACE] = ITEM_FLAG_NECKLACE;
	mFlagArray[INVENTORY_WEAR_BROOCH] = ITEM_FLAG_BROOCH;
	mFlagArray[INVENTORY_WEAR_BRACELET] = ITEM_FLAG_BRACELET;
	mFlagArray[INVENTORY_WEAR_RING] = ITEM_FLAG_RING;

	mFlagArray[INVENTORY_WEAR_CARD1] = ITEM_FLAG_EQUIPCARD;
	mFlagArray[INVENTORY_WEAR_CARD2] = ITEM_FLAG_EQUIPCARD;
	mFlagArray[INVENTORY_WEAR_CARD3] = ITEM_FLAG_EQUIPCARD;

	mFlagArray[INVENTORY_HAND_LEFT1] = ITEM_FLAG_SHIELD;
	mFlagArray[INVENTORY_HAND_RIGHT1] = ITEM_FLAG_SWORD | ITEM_FLAG_BLADE | ITEM_FLAG_CUTTER | ITEM_FLAG_GUN | ITEM_FLAG_STAFF | ITEM_FLAG_DUAL;
	mFlagArray[INVENTORY_HAND_LEFT2] = ITEM_FLAG_SHIELD;
	mFlagArray[INVENTORY_HAND_RIGHT2] = ITEM_FLAG_SWORD | ITEM_FLAG_BLADE | ITEM_FLAG_CUTTER | ITEM_FLAG_GUN | ITEM_FLAG_STAFF | ITEM_FLAG_DUAL;

	for( unsigned int i = INVENTORY_BAG0_BEGIN; i <= INVENTORY_BAG3_END; ++i )
	{
		mFlagArray[i] = ITEM_FLAG_ALL;
	}

	/// 네트워크 정보
	mSlotIndex0 = 0;
	mSlotIndex1 = 0;
	mValue = 0;
	mTempIndex = 0;
	mActiveWeapon = ItemActiveMax;

	mFrontLeft.Set( 0, 0, 0, 0 );
	mFrontRight.Set( 0, 0, 0, 0 );
	mBackLeft.Set( 0, 0, 0, 0 );
	mBackRight.Set( 0, 0, 0, 0 );
}

cItemManager::~cItemManager()
{
	mSingleton = 0;

	delete mItemText;

	/// 정의
	{
		cDefineMap::cIterator i = mDefineMap.Begin();
		cDefineMap::cIterator iend = mDefineMap.End();

		for( ; i != iend; ++i )
		{
			delete (cItemDefine*)(i->mSecond);
		}
		mDefineMap.Clear();
	}

	/// 능력
	{
		cAbilityMap::cIterator i = mAbilityMap.Begin();
		cAbilityMap::cIterator iend = mAbilityMap.End();

		for( ; i != iend; ++i )
		{
			delete (cItemAbility*)(i->mSecond);
		}
		mAbilityMap.Clear();
	}

	/// 제한
	{
		cLimitMap::cIterator i = mLimitMap.Begin();
		cLimitMap::cIterator iend = mLimitMap.End();

		for( ; i != iend; ++i )
		{
			delete (cItemLimit*)(i->mSecond);
		}
		mLimitMap.Clear();
	}

	/// 카드
	{
		cCardMap::cIterator i = mCardMap.Begin();
		cCardMap::cIterator iend = mCardMap.End();

		for( ; i != iend; ++i )
		{
			delete (cItemCard*)(i->mSecond);
		}
		mCardMap.Clear();
	}

	/// 타로
	{
		cTarotMap::cIterator i = mTarotMap.Begin();
		cTarotMap::cIterator iend = mTarotMap.End();

		for( ; i != iend; ++i )
		{
			delete (cItemTarot*)(i->mSecond);
		}
		mTarotMap.Clear();
	}

	/// 스프레드
	{
		cSpreadMap::cIterator i = mSpreadMap.Begin();
		cSpreadMap::cIterator iend = mSpreadMap.End();

		for( ; i != iend; ++i )
		{
			delete (cItemSpread*)(i->mSecond);
		}
		mSpreadMap.Clear();
	}

	/// 파일명
	{
		cFileNamesMap::cIterator i = mFileNamesMap.Begin();
		cFileNamesMap::cIterator iend = mFileNamesMap.End();

		for( ; i != iend; ++i )
		{
			delete [] ((cString*)(i->mSecond));
		}
		mFileNamesMap.Clear();
	}
	
	/// 분해 데이터
	{
		cDisjointMap::cIterator i = mDisjointMap.Begin();
		cDisjointMap::cIterator end = mDisjointMap.End();

		for( ; i != end; ++i )
		{	
			delete (sItemDisjoint*)(i->mSecond);
		}
		mDisjointMap.Clear();
	}	

	/// 강화 데이터
	{
		cEnhancedMap::cIterator i = mEnhancedMap.Begin();
		cEnhancedMap::cIterator end = mEnhancedMap.End();

		for( ; i != end; ++i )
		{
			delete (sItemEnhanced*)(i->mSecond);
		}
		mEnhancedMap.Clear();
	}

	/// 카드장착 데이터
	{
		cPutCardSlotMap::cIterator i = mPutCardSlotMap.Begin();
		cPutCardSlotMap::cIterator end = mPutCardSlotMap.End();

		for( ; i != end; ++i )
		{
			delete (sItemPutCardSlot*)(i->mSecond);
		}
		mPutCardSlotMap.Clear();
	}

	/// Npc 상점
	{
		cNpcStoreMap::cIterator i = mNpcStoreMap.Begin();
		cNpcStoreMap::cIterator end = mNpcStoreMap.End();

		for( ; i != end; ++i )
		{
			delete (cItemNpcStore*)(i->mSecond);
		}
		mNpcStoreMap.Clear();
	}
	/// 아이템 총갯수
	{
		mItemCountMap.Clear();
	}

	/// 아이템 분류
	{
		mHighClassArr.Clear();

		cNameIdxArrMap::cIterator i, end;
		cNameIdxArr* idxArr = 0;

		i = mMiddleClassMap.Begin();
		end = mMiddleClassMap.End();
		for( ; i != end; ++i )
		{
			idxArr = (cNameIdxArr*)(*i).mSecond;
			idxArr->Clear();
			SAFE_DELETE( idxArr );
		}
		mMiddleClassMap.Clear();

		i = mLowClassMap.Begin();
		end = mLowClassMap.End();
		for( ; i != end; ++i )
		{
			idxArr = (cNameIdxArr*)(*i).mSecond;
			idxArr->Clear();
			SAFE_DELETE( idxArr );
		}
		mLowClassMap.Clear();

		i = mItemMap.Begin();
		end = mItemMap.End();
		for( ; i != end; ++i )
		{
			idxArr = (cNameIdxArr*)(*i).mSecond;
			idxArr->Clear();
			SAFE_DELETE( idxArr );
		}
		mItemMap.Clear();

#ifdef _GMTOOL
		i = mGMItemMap.Begin();
		end = mGMItemMap.End();
		for( ; i != end; ++i )
		{
			idxArr = (cNameIdxArr*)(*i).mSecond;
			idxArr->Clear();
			SAFE_DELETE( idxArr );
		}
		mGMItemMap.Clear();
#endif
	}

	mDropItemMap.Clear();
}

bool cItemManager::Init()
{
	mItemText = new cUIText;

	if( LoadText( ITEM_TEXT_FILENAME ) == false )
	{
		assert( 0 && "failed to load item text" );
		return false;
	}

	if( LoadFileName( ITEM_FILENAME_FILENAME ) == false )
	{
		assert( 0 && "failed to load item file name" );
		return false;
	}

	if( LoadAbility( ITEM_ABILITY_FILENAME ) == false )
	{
		assert( 0 && "failed to load item ability" );
		return false;
	}

	if( LoadLimit( ITEM_LIMIT_FILENAME ) == false )
	{
		assert( 0 && "failed to load item limit" );
		return false;
	}

	if( LoadCard( ITEM_CARD_FILENAME ) == false )
	{
		assert( 0 && "failed to load item card" );
		return false;
	}

	if( LoadTarot( ITEM_TAROT_FILENAME ) == false )
	{
		assert( 0 && "failed to load item tarot" );
		return false;
	}

	if( LoadSpread( ITEM_SPREAD_FILENAME ) == false )
	{
		assert( 0 && "failed to load item spread" );
		return false;
	}

	if( LoadDisjoint( ITEM_DISJOINT_FILENAME ) == false )
	{
		assert( 0 && "failed to load item disjoint" );
		return false;
	}

	if( LoadEnhanced( ITEM_ENHANCED_FILENAME ) == false )
	{
		assert( 0 && "failed to load item enhanced" );
		return false;
	}

	if( LoadCardSlot( ITEM_CARDSLOT_FILENAME ) == false )
	{
		assert( 0 && "failed to load item card slot" );
		return false;
	}

	/// 위의 데이터를 참조하므로 가장 나중에 로드한다
	if( LoadDefine( ITEM_DEFINE_FILENAME ) == false )
	{
		assert( 0 && "failed to load item define" );
		return false;
	}

	if( LoadNpcStore( ITEM_NPCSTORE_FILENAME ) == false )
	{
		assert( 0 && "failed to load npc store" );
		return false;
	}

	if( LoadCategoryTable( ITEM_CATEGORY_FILENAME ) == false )
	{
		assert( 0 && "failed to load category table" );
		return false;
	}

	/// 쿨타임에 쿨타임관련 데이터 세팅
	LoadCoolData();
	return true;
}

/// game in 시에 데이터 세팅
void cItemManager::Open()
{
	/// 무기 장착 변경
	SetSwitchWeapon( mActiveWeapon );
}

void cItemManager::Close()
{
	/// 초기화 
	mActiveWeapon = ItemActiveMax;

	/// 총 갯수 세기 초기화
	mItemCountMap.Clear();
	mDropItemMap.Clear();

	/// 쿨타임 삭제
	COOLMAN->Clear();

	/// 퀵슬롯 삭제
	QUICKMAN->Clear();

	/// 아이템 모두 삭제
	for( unsigned int i=MIN_INVENTORY; i<MAX_INVENTORY; ++i )
	{
		mItemArray[i] = 0;
	}

	mCurWeight = 0.f;
	mMaxWeight = 0.f;
	mLastAccutime = 0;

	/// 거래 사용자 정보 클리어
	mTradeTarget = 0;
	mTradeMoney  = 0;
	mTradeName.Clear();
	mUserSellName.Clear();
	mUserSellTarget = 0;

	/// 아이템 관련 락 풀기
	/// 초기화용
	mLocked = false;
	mTry = ITEM_TRY_NULL;

	if( mSlotIndex0 < MAX_INVENTORY )
	{
		cItem& item0 = mItemArray[mSlotIndex0];
		if( item0.GetIcon() )
			item0.SetUsedFlag( true );
	}

	if( mSlotIndex1 < MAX_INVENTORY )
	{
		cItem& item1 = mItemArray[mSlotIndex1];
		if( item1.GetIcon() )
			item1.SetUsedFlag( true );
	}

	mSlotIndex0 = 0;
	mSlotIndex1 = 0;
	mValue = 0;
}

bool cItemManager::LoadText( const cString& pathName )
{
	if( mItemText->Load( pathName ) == false )
	{
		assert( 0 && "failed to load item text" );
		return false;
	}
	return true;
}

LPCTSTR cItemManager::GetItemName( unsigned int i )
{
	return mItemText->GetText( i ).Cstr();
}

cItemDefine* cItemManager::GetItemDefine( long itemIndex )
{
	if( itemIndex == 0 )
		return 0;

	cDefineMap::cConstIterator i = mDefineMap.Find( itemIndex );

	if( i == mDefineMap.End() )
		return 0;
	else
		return (cItemDefine*)i->mSecond;
}

cItemAbility* cItemManager::GetItemAbility( long itemIndex )
{
	if( itemIndex == 0 )
		return 0;

	cAbilityMap::cConstIterator i = mAbilityMap.Find( itemIndex );

	if( i == mAbilityMap.End() )
		return 0;
	else
		return (cItemAbility*)i->mSecond;
}

cItemLimit* cItemManager::GetItemLimit( long itemIndex )
{
	if( itemIndex == 0 )
		return 0;

	cLimitMap::cConstIterator i = mLimitMap.Find( itemIndex );

	if( i == mLimitMap.End() )
		return 0;
	else
		return (cItemLimit*)i->mSecond;
}

cItemCard* cItemManager::GetItemCard( long itemIndex )
{
	cCardMap::cConstIterator i = mCardMap.Find( itemIndex );

	if( i == mCardMap.End() )
		return 0;
	else
		return (cItemCard*)i->mSecond;
}

cItemTarot* cItemManager::GetItemTarot( long itemIndex )
{
	if( itemIndex == 0 )
		return 0;

	cTarotMap::cConstIterator i = mTarotMap.Find( itemIndex );
	
	if( i == mTarotMap.End() )
		return 0;
	else
		return (cItemTarot*)i->mSecond;
}

cItemSpread* cItemManager::GetItemSpread( long itemIndex )
{
	if( itemIndex == 0 )
		return 0;

	cSpreadMap::cConstIterator i = mSpreadMap.Find( itemIndex );

	if( i == mSpreadMap.End() )
		return 0;
	else
		return (cItemSpread*)i->mSecond;
}

cString* cItemManager::GetItemFileNames( long itemIndex )
{
	if( itemIndex == 0 )
		return 0;

	cFileNamesMap::cConstIterator i = mFileNamesMap.Find( itemIndex );

	if( i == mFileNamesMap.End() )
		return 0;
	else
		return (cString*)i->mSecond;
}

sItemDisjoint* cItemManager::GetItemDisjoint( long index )
{
	if( index == 0 )
		return 0;

	cDisjointMap::cConstIterator i = mDisjointMap.Find( index );
	
	if( i == mDisjointMap.End() )
		return 0;
	else
		return (sItemDisjoint*)(i->mSecond);
}

sItemEnhanced* cItemManager::GetItemEnhanced( long index )
{
	if( index == 0 )
		return 0;

	cEnhancedMap::cConstIterator i = mEnhancedMap.Find( index );

	if( i == mEnhancedMap.End() )
		return 0;
	else
		return (sItemEnhanced*)(i->mSecond);
}

sItemPutCardSlot* cItemManager::GetItemPutCardSlot( long index )
{
	cPutCardSlotMap::cConstIterator i = mPutCardSlotMap.Find( index );

	if( i == mPutCardSlotMap.End() )
		return 0;
	else
		return (sItemPutCardSlot*)(i->mSecond);
}


unsigned int cItemManager::GetItemCount( long itemIndex )
{
	if( itemIndex == 0 )
		return 0;

	cItemCountMap::cConstIterator i = mItemCountMap.Find( itemIndex );

	if( i == mItemCountMap.End() )
		return 0;
	else
		return (unsigned int)i->mSecond;
}

/// 아이템인덱스로 슬롯 번호 찾기 
unsigned int cItemManager::FindSlotIndex( long itemIndex )
{
	for( unsigned int slot = INVENTORY_BAG0_BEGIN; slot <= INVENTORY_QUEST_END; ++slot )
	{
		cItem& item = mItemArray[slot];
		if( item.mIndex > 0 && item.mIndex == (unsigned long)itemIndex )
			return slot;
	}
	return 0;
}

/// 인벤, 가방중 한개의 윈도우만 선택된 아이콘을 갖도록 한다
void cItemManager::SetInvenSelect( cUIWindow* win )
{
	cInventoryWindow* inven = GAMEUI->GetInventoryWindow();
	cBagWindow* bag1 = GAMEUI->GetBagWindow(0);
	cBagWindow* bag2 = GAMEUI->GetBagWindow(1);
	cBagWindow* bag3 = GAMEUI->GetBagWindow(2);

	if( inven != win )
		inven->HideSelect();
	if( bag1 != win )
		bag1->HideSelect();
	if( bag2 != win )
		bag2->HideSelect();
	if( bag3 != win )
		bag3->HideSelect();
}

void cItemManager::ChangeSelectSlot( unsigned int slot )
{
	/// UI 갱신
	eItemIn in = GetItemIn( slot );
	if( in == ITEM_IN_INVEN_PRIVATE || in == ITEM_IN_EQUIP )
	{
		/// 인벤
		if( slot <= INVENTORY_BAG0_END || ( slot >= INVENTORY_MALL_BEGIN && slot <= INVENTORY_MALL_END ))
		{
			cInventoryWindow* inven = GAMEUI->GetInventoryWindow();
			if( inven )
				inven->ChangeSelect( slot );
		}
		/// 가방1
		else if( slot >= INVENTORY_BAG1_BEGIN && slot <= INVENTORY_BAG1_END )
		{
			cBagWindow* bag1 = GAMEUI->GetBagWindow(0);
			if( bag1 )
				bag1->ChangeSelect( slot );
		}
		/// 가방2
		else if( slot >= INVENTORY_BAG2_BEGIN && slot <= INVENTORY_BAG2_END )
		{
			cBagWindow* bag2 = GAMEUI->GetBagWindow(1);
			if( bag2 )
				bag2->ChangeSelect( slot );
		}
		/// 가방3
		else if( slot >= INVENTORY_BAG3_BEGIN && slot <= INVENTORY_BAG3_END )
		{
			cBagWindow* bag3 = GAMEUI->GetBagWindow(2);
			if( bag3 )
				bag3->ChangeSelect( slot );
		}
		else
		{
			assert(0);
		}
	}
	else if( in == ITEM_IN_WAREHOUSE_PRIVATE )
	{
		if( slot >= INVENTORY_WAREHOUSE0_BEGIN && slot <= INVENTORY_WAREHOUSE0_END )
		{
			 cWareHouseWindow* ware = GAMEUI->GetWareHouseWindow();
			 if( ware )
				 ware->ChangeSelect( slot );
		}
		else if( slot >= INVENTORY_WAREHOUSE1_BEGIN && slot <= INVENTORY_WAREHOUSE1_END )
		{
			cWareHouse2Window* ware2 = GAMEUI->GetWareHouse2Window();
			if( ware2 )
				ware2->ChangeSelect( slot );
		}
	}
	else if( in == ITEM_IN_WAREHOUSE_MALL )
	{
		cWareHouseWindow* ware = GAMEUI->GetWareHouseWindow();
		if( ware )
			ware->ChangeSelect( slot );
	}
}

eItemIn cItemManager::GetItemIn( unsigned int i )
{
	if( i >= INVENTORY_EQUIP_BEGIN && i <= INVENTORY_EQUIP_END )
		return ITEM_IN_EQUIP;
	else if( i >= INVENTORY_BAG_BEGIN && i <= INVENTORY_BAG_END )
		return ITEM_IN_INVEN_PRIVATE;
	else if( i >= INVENTORY_QUEST_BEGIN && i <= INVENTORY_QUEST_END )
		return ITEM_IN_INVEN_QUEST;
	else if( i >= INVENTORY_MALL_BEGIN && i <= INVENTORY_MALL_END )
		return ITEM_IN_INVEN_MALL;
	else if( i >= INVENTORY_WAREHOUSE0_BEGIN && i <= INVENTORY_WAREHOUSE1_END )
		return ITEM_IN_WAREHOUSE_PRIVATE;
	else if( i >= INVENTORY_WAREHOUSE2_BEGIN && i <= INVENTORY_WAREHOUSE3_END )
		return ITEM_IN_WAREHOUSE_MALL;
	else if( i >= INVENTORY_TAROT_BEGIN && i <= INVENTORY_TAROT_END )
		return ITEM_IN_CARDBOOK_TAROT;
	else if( i >= INVENTORY_SPREAD_BEGIN && i <= INVENTORY_SPREAD_END )
		return ITEM_IN_CARDBOOK_SPREAD;
	else if( i >= NPCSTORE_SLOT_BEGIN && i <= NPCSTORE_SLOT_END )
		return ITEM_IN_NPCSTORE;
	else if( i == DISJOINT_SLOT )
		return ITEM_IN_DISJOINT;
	else if( i == ENHANCED_ITEM_SLOT )
		return ITEM_IN_ENHANCED_ITEM;
	else if( i == ENHANCED_CARD_SLOT )
		return ITEM_IN_ENHANCED_CARD;
	else if( i == PUTCARD_ITEM_SLOT )
		return ITEM_IN_PUTCARD_ITEMSLOT;
	else if( i >= PUTCARD_CARD_SLOT_BEGIN && i <= PUTCARD_CARD_SLOT_END )
		return ITEM_IN_PUTCARD_CARDSLOT;
	else
		return ITEM_IN_NULL;
}

/// 쿨타임 세팅
void cItemManager::StartCoolTime( unsigned long itemIndex, unsigned long coolTime )
{
	for( unsigned int slot = INVENTORY_BAG0_BEGIN; slot <= INVENTORY_BAG3_END; ++slot )
	{
		cItem& item = ITEMMAN->mItemArray[slot];

		if( item.mIndex == itemIndex )
		{
			if( item.StartCoolTime( coolTime ) == false )
			{
				assert(0);
				continue;
			}
		}
	}

	/// 퀵슬롯도 세팅하도록한다.
	QUICKMAN->StartCoolTime( itemIndex, coolTime );
}

void cItemManager::EndCoolTime( unsigned long itemIndex )
{
	for( unsigned int slot = INVENTORY_BAG0_BEGIN; slot <= INVENTORY_BAG3_END; ++slot )
	{
		cItem& item = ITEMMAN->mItemArray[slot];

		if( item.mIndex == itemIndex )
			item.EndCoolTime();
	}

	/// 퀵슬롯도 세팅하도록한다.
	QUICKMAN->EndCoolTime( itemIndex );
}

/// 쿨타임복사
void cItemManager::CopyCoolTime( unsigned long itemIndex, unsigned long startTime, unsigned long restTime, unsigned long totalTime )
{
	for( unsigned int slot = INVENTORY_BAG0_BEGIN; slot <= INVENTORY_BAG3_END; ++slot )
	{
		cItem& item = ITEMMAN->mItemArray[slot];

		if( item.mIndex == itemIndex )
			item.CopyCoolTime( startTime, restTime, totalTime );
	}
}

/// 게임접속시, 쿨타임 매니저로부터 모든 아이템의 쿨타임을 복사한다 
void cItemManager::SetAllItemCool()
{
	for( unsigned int slot = INVENTORY_BAG0_BEGIN; slot <= INVENTORY_BAG3_END; ++slot )
	{
		cItem& item = ITEMMAN->mItemArray[slot];
		if( item.mIndex > 0 )
			COOLMAN->CopyCoolTime( item.mIndex );
	}

	QUICKMAN->SetAllItemCool();
}

void cItemManager::BindIcon( unsigned int i, cItemIcon* icon )
{
	assert( i < MAX_INVENTORY && "index out of range" );
	assert( icon && "null icon" );

	/// 아이콘 바인딩
	mItemArray[i].BindIcon( icon );
	
	///
	icon->SetSlotIndex( i );

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

/// 백업용
void cItemManager::LinkIcon( cItemIcon* icon )
{
	assert( icon );

	if( mLinkedIcon == icon )
		return;

	if( mLinkedIcon )
	{
		mLinkedIcon->SetColor( NiColorA::WHITE );
		assert(0);
	}

	mLinkedIcon = icon;
	mLinkedIcon->ShowGauge( false );
	mLinkedIcon->SetColor( 0.5f, 0.5f, 0.5f, 1.0f );
}

/// 백업용
void cItemManager::UnLinkIcon( bool setcolor )
{
	if( mLinkedIcon )
	{
		mLinkedIcon->ShowGauge( true );

		if( setcolor )
			mLinkedIcon->SetColor( NiColorA::WHITE );

		mLinkedIcon = 0;
	}
}

void cItemManager::ClearColor(unsigned int slotIndex )
{
	cItem& item = mItemArray[slotIndex];
	item.mIcon->SetColor( NiColorA::WHITE );
}

bool cItemManager::FindEmptySlot( unsigned int* slotIndex, unsigned int begin, unsigned int end )
{
	assert( slotIndex );

	for( unsigned int i = begin; i <= end; ++i )
	{
		if( mItemArray[i].mCount == 0 )
		{
			*slotIndex = i;
			return true;
		}
	}
	return false;
}

bool cItemManager::TryToMoveItem( unsigned int slotIndex0, unsigned int slotIndex1, cItemIcon* icon )
{
	assert( slotIndex0 <= MAX_INVENTORY && "index out of range" );
	assert( slotIndex1 <= MAX_INVENTORY && "index out of range" );
	assert( slotIndex0 != slotIndex1 );

	if( IsLocked() || slotIndex0 == slotIndex1 )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

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

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

	///
	cItem& item0 = mItemArray[slotIndex0];
	cItem& item1 = mItemArray[slotIndex1];
	cItemDefine* itemDefine = item0.mDefine;
	assert( itemDefine );

	if( slotIndex0 == INVENTORY_HAND_LEFT2 || 
		slotIndex0 == INVENTORY_HAND_RIGHT2 ||
		slotIndex1 == INVENTORY_HAND_LEFT2 ||
		slotIndex1 == INVENTORY_HAND_RIGHT2 )
	{
		/// 스킬 동작중 장비교체 불가
        if( HERO->IsReadyUseSkill() == false )
			return false;

		/// 사용 제약조건 체크
		if( CheckLimit( slotIndex0 ) == false )
		{
			CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 239 ) );
			return false;
		}
		if( CheckLimit( slotIndex1 ) == false )
		{
			CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 239 ) );
			return false;
		}
	}

	unsigned short count = item0.mCount;

	/// 장착 -> 인벤 개인
	if( in0 == ITEM_IN_EQUIP && in1 == ITEM_IN_INVEN_PRIVATE )
	{
		if( item1.mCount && (item1.mFlag & mFlagArray[slotIndex0] ) != item1.mFlag )
			return false;
		if( TestMoveItemDown( slotIndex0, slotIndex1 ) == false )
			return false;
	}
	/// 인벤 개인 -> 장착
	else if( in0 == ITEM_IN_INVEN_PRIVATE && in1 == ITEM_IN_EQUIP )
	{
		if( item0.mEquipType == ITEM_EQUIP_TWO_HANDS )
		{
			if( slotIndex1 == INVENTORY_HAND_LEFT1 )
				slotIndex1 = INVENTORY_HAND_RIGHT1;
			else if( slotIndex1 == INVENTORY_HAND_LEFT2 )
				slotIndex1 = INVENTORY_HAND_RIGHT2;
		}
		if( item0.mFlag == ITEM_FLAG_NULL || item0.mFlag == ITEM_FLAG_UNKNOWN )
			return false;
		if( item0.mCount && (item0.mFlag & mFlagArray[slotIndex1] ) != item0.mFlag )
			return false;
		if( TestMoveItemUp( slotIndex0, slotIndex1 ) == false )
			return false;
	}
	/// 인벤 개인 -> 인벤 개인, 인벤 몰 -> 인벤 몰
	else if( (in0 == ITEM_IN_INVEN_PRIVATE || in0 == ITEM_IN_INVEN_MALL) && in0 == in1 )
	{
		/// 걍 넘어감
	}
	/// 창고 개인 -> 창고 개인, 창고 몰 -> 창고 몰
	else if( (in0 == ITEM_IN_WAREHOUSE_PRIVATE || in0 == ITEM_IN_WAREHOUSE_MALL) && in0 == in1 )
	{
		if( item1.mCount )
			return false;
	}
	/// 인벤 개인 <-> 창고 개인
	/// 인벤 몰 <-> 창고 몰
	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 false;

		/// 창고 -> 인벤 개인
		if( in0 == ITEM_IN_WAREHOUSE_PRIVATE && in1 == ITEM_IN_INVEN_PRIVATE )
		{
			if( CheckMoveItem( item0.mIndex, item0.mCount ) == false )
				return false;
		}
	}
	else
		return false;

	/// 네트워크 메시지 전송
	/// 인벤 <-> 인벤, 인벤 개인 <-> 장착, 창고 <-> 창고
	if( (in0 == ITEM_IN_INVEN_PRIVATE && in0 == in1) ||
		(in0 == ITEM_IN_INVEN_MALL && in0 == in1) ||
		(in0 == ITEM_IN_INVEN_PRIVATE && in1 == ITEM_IN_EQUIP) ||
		(in0 == ITEM_IN_EQUIP && in1 == ITEM_IN_INVEN_PRIVATE) ||
		(in0 == ITEM_IN_WAREHOUSE_PRIVATE && in0 == in1) ||
		(in0 == ITEM_IN_WAREHOUSE_MALL && in0 == in1) )
	{
		MSG_REQ_ITEM_MOV_INVENTORY msg;
		::memset( &msg, 0, sizeof( msg ) );

		msg.Category = NM_ITEM;
		msg.Protocol = NM_ITEM_MOV_INVENTORY_REQ;
		msg.number1 = (unsigned short)slotIndex0;
		msg.number2 = (unsigned short)slotIndex1;

		NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
	}
	/// 인벤 개인 <-> 창고 개인, 인벤 몰 <-> 창고 몰
	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) )
	{
		MSG_REQ_NPC_ITEM_MOV2_INVENTORY msg;
		::memset( &msg, 0, sizeof( msg ) );

		msg.Category = NM_NPC;
		msg.Protocol = NM_NPC_ITEM_MOV2_INVENTORY_REQ;
		msg.npcIdx = HERO->GetNpcIdx();
		msg.number1 = (unsigned short)slotIndex0;
		msg.number2 = (unsigned short)slotIndex1;
		msg.count = count;

		NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
	}
	else
	{
		assert( 0 );
		return false;
	}

	/// 잠금
	LockAndBackup( ITEM_TRY_MOVE, slotIndex0, slotIndex1, 0, 0, 0, icon );
	return true;
}

/// 맵 체인지 아이템 사용
bool cItemManager::TryToUseMapChange( unsigned int slotIndex )
{
	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	/// 사용
	MSG_REQ_ITEM_USE_INVENTORY msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category    = NM_ITEM;
	msg.Protocol    = NM_ITEM_USE_INVENTORY_REQ;
	msg.targetType = HERO->GetObjectType();
	msg.targetIndex = HERO->GetObjectID();
	msg.number = (unsigned short)slotIndex;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 잠금
	LockAndBackup( ITEM_TRY_USE, slotIndex );
	return true;
}

/// 아이템 사용
bool cItemManager::TryToEquipItem( unsigned int slotIndex )
{
	assert( slotIndex <= MAX_INVENTORY && "index out of range" );

	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	/// 사용 제약조건 체크
	if( CheckLimit( slotIndex ) == false )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 239 ) );
		return false;
	}

	/// 장착
	cItem& item = mItemArray[slotIndex];
	cItemDefine* itemDefine = item.mDefine;
	if( !itemDefine )
		return false;

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

	/// 거래등으로 LOCK 걸려있으면 사용가능한 다른아이템 찾는다
	if( item.IsLock() == true && (type == ITEM_ETC1 || (type == ITEM_CARD && subType == ITEM_CARD_COMMON )) )
	{
		unsigned int findSlot = 0;
		for( unsigned int i = INVENTORY_BAG0_BEGIN; i <= INVENTORY_MALL_END; ++i )
		{	
			cItem& otherItem = mItemArray[i];
			if( otherItem.mIndex > 0 && otherItem.mIndex == item.mIndex )
			{
				/// 다른 슬롯의 동일한 아이템 있는지 찾기
				if( i != slotIndex )
				{
					findSlot = i;
					break;
				}
			}
		}
	
		/// 못찾으면 리턴
		if( findSlot > 0 )
			slotIndex = findSlot;
		else
			return false;
	}
	/// 그 외아이템이 lock이면 리턴
	else if( item.IsLock() == true )
		return false;

	/// 상태검사 - 조합관련이 아닐떄
	if( !(type == ITEM_ETC1 && (subType == ITEM_ETC1_MIXSKILL || subType == ITEM_ETC1_RECIPE || subType == ITEM_ETC1_RECIPEGROUP)) )
	{
		if( HERO->GetStopFlag() == eSTOP_ITEMMIX )
		{
			CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
			return false;
		}
	}

	switch( type )
	{
	case ITEM_WEAPON:
		if( TestEquipWeapon( i1, item.mEquipType ) == false )
			return false;
		break;
	case ITEM_WEAR:
		if( TestEquipWear( i1, subType ) == false )
			return false;
		break;
	case ITEM_ACCESSORY:
		if( TestEquipAccessory( i1, subType ) == false )
			return false;
		break;
	case ITEM_ETC1:
		{
			if( subType == ITEM_ETC1_QUEST || subType == ITEM_ETC1_MIXSKILL || subType == ITEM_ETC1_RECIPE || subType == ITEM_ETC1_RECIPEGROUP )
			{
				if( TestUseEtcItem( slotIndex ) == false )
					return false;
			}
			else if( subType == ITEM_ETC1_SKILLRESET )
			{
			}
			else
			{
				if( TestUseItem( slotIndex ) == false )
					return false;
			}
		}
		break;
	case ITEM_MATERIAL:
		if( subType == ITEM_MATERIAL_MAP )
		{
			if( TestUseItem( slotIndex ) == false )
				return false;
		}
		break;
	case ITEM_SPREAD:
		{
			cCardBookWindow* cardBook = (cCardBookWindow*)GAMEUI->GetCardBookWindow();
			if( cardBook )
			{
				cTarotSheetWindow* sheet = cardBook->GetTarotSheet();
				if( !sheet )
					return false;

				/// 
				unsigned int emptyItemSlot = sheet->GetEmptySlotIndex();
				unsigned long registItemIdx = sheet->IsRegistItem( emptyItemSlot - INVENTORY_TAROT_BEGIN );
				if( !(registItemIdx == ULONG_MAX ) )
				{
					eMSGBox_Event event = (registItemIdx == 0)? eMBEVENT_ITEM_CARDBOOK_SPREADNEW : eMBEVENT_ITEM_CARDBOOK_SPREADUPDATE;
					GAMEUI->ShowItemCardBook( event, slotIndex, emptyItemSlot, registItemIdx );
				}
			}
		}
		break;
	case ITEM_CARD:
		if( subType == ITEM_CARD_TAROT )
		{
			cCardBookWindow* cardBook = (cCardBookWindow*)GAMEUI->GetCardBookWindow();
			if( cardBook )
			{
				cItemTarot* tarot = itemDefine->GetTarotDefine();
				if( !tarot )
					return false;

				cTarotSheetWindow* sheet = cardBook->GetTarotSheet();
				if( !sheet )
					return false;

				unsigned long registItemIdx = sheet->IsRegistItem( tarot->GetUniqueNumber() );
				unsigned int bookslotIndex = sheet->GetSlotIndex( tarot->GetUniqueNumber() );
				if( !(registItemIdx == ULONG_MAX || bookslotIndex == ULONG_MAX) )
				{
					eMSGBox_Event event = (registItemIdx == 0)? eMBEVENT_ITEM_CARDBOOK_TAROTNEW : eMBEVENT_ITEM_CARDBOOK_TAROTUPDATE;
					GAMEUI->ShowItemCardBook( event, slotIndex, bookslotIndex, registItemIdx );
				}
			}
		}
		if( subType == ITEM_CARD_COMMON )	/// 소모용 카드이면 사용
		{
			/// 대기상태 아니면 소모용 카드 사용 불가
			if( !( HERO->GetState() == eOBJECT_STATE_IDLE || HERO->GetState() == ePLAYER_STATE_ITEMPICK ) )
			{
				CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 242 ) );
				return false;
			}

			if( TestUseItem( slotIndex ) == false )
				return false;
		}
		if( subType == ITEM_CARD_EQUIP_C )	/// 캐릭터 장착 카드
		{
			if( TestEquipCard( i1 ) == false )
				return false;
		}
		break;
	default:
		return false;
	}

	/// 네트워크 메시지 전송
	switch( type )
	{
	case ITEM_WEAPON:
	case ITEM_WEAR:
	case ITEM_ACCESSORY:
		{
			MSG_REQ_ITEM_MOV_INVENTORY msg;
			::memset( &msg, 0, sizeof( msg ) );

			msg.Category = NM_ITEM;
			msg.Protocol = NM_ITEM_MOV_INVENTORY_REQ;
			msg.number1 = (unsigned short)slotIndex;
			msg.number2 = (unsigned short)i1;

			NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

			/// 잠금
			LockAndBackup( ITEM_TRY_EQUIP, slotIndex );
		}
		break;
	case ITEM_ETC1:
		if( subType == ITEM_ETC1_QUEST )
		{
			cStringT str;
			cItemAbility* abil = itemDefine->GetAbililty();
			if( !abil )
			{
				assert(0);
				return false;
			}
			
			unsigned long questIdx = abil->GetInfluenceIndex();
			str.Format( GAMERESOURCEMAN->GetGameText( 434 ), GAMERESOURCEMAN->GetQuestTitle( questIdx ) );
			UIMAN->CreateModal(	eStage_Game,
								eMBEVENT_QUEST_ADDBYITEM, 
								(LPCTSTR)str.Cstr(),	
								GAMERESOURCEMAN->GetGameText( 301 ),	 // 에러
								eSKIN_YESNO,
								(void*)slotIndex
								);
		}
		else if( subType == ITEM_ETC1_CHANGE )
		{
			/// 체인지 아이템
			MSG_REQ_ITEM_CHANGE_INVENTORY msg;
			::memset( &msg, 0, sizeof( msg ) );

			msg.Category = NM_ITEM;
			msg.Protocol = NM_ITEM_CHANGE_INVENTORY_REQ;
			msg.number = (unsigned short)slotIndex;
			NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

			/// 잠금
			LockAndBackup( ITEM_TRY_CHANGE, slotIndex );
		}
		else if( subType == ITEM_ETC1_MIXSKILL )
		{
			cItem& item = mItemArray[slotIndex];
			cItemAbility* itemAbil = item.mDefine->GetAbililty();
			if( itemAbil )
			{
				if( ITEMMIXMAN->ItemMixUseMakeSkill( slotIndex, itemAbil->GetInfluenceIndex() ) == true )
				{
					LockAndBackup( ITEM_TRY_MIXSKILL, slotIndex );
				}
			}
			else
			{
				assert(0);
				return false;
			}
		}
		else if( subType == ITEM_ETC1_RECIPE )
		{
			cItem& item = mItemArray[slotIndex];
			cItemAbility* itemAbil = item.mDefine->GetAbililty();
			if( itemAbil )
			{
				if( ITEMMIXMAN->ItemMixUseRecipe( slotIndex, itemAbil->GetInfluenceIndex() ) == true )
				{
					/// 잠금
					LockAndBackup( ITEM_TRY_MIXSKILL, slotIndex );
				}
			}
			else
			{
				assert(0);
				return false;
			}
		}
		else if( subType == ITEM_ETC1_RECIPEGROUP )
		{
			cItem& item = mItemArray[slotIndex];
			cItemAbility* itemAbil = item.mDefine->GetAbililty();
			if( itemAbil )
			{
				if( ITEMMIXMAN->ItemMixUseRecipeGroup( slotIndex, itemAbil->GetInfluenceIndex() ) == true )
				{
					/// 잠금
					LockAndBackup( ITEM_TRY_MIXSKILL, slotIndex );
				}
			}
			else
			{
				assert(0);
				return false;
			}
		}
		else if( subType == ITEM_ETC1_SKILLRESET )
		{
			MSG_REQ_PLAYER_SKILLRESET msg;
			::memset( &msg, 0, sizeof( msg ) );

			msg.Category = NM_PLAYER;
			msg.Protocol = NM_PLAYER_SKILLRESET_REQ;
			msg.mSlotNum = (unsigned short)slotIndex;
			NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
		}
		else
		{
			/// 사용
			MSG_REQ_ITEM_USE_INVENTORY msg;
			::memset( &msg, 0, sizeof( msg ) );

			msg.Category    = NM_ITEM;
			msg.Protocol    = NM_ITEM_USE_INVENTORY_REQ;

			const sObject* target = HERO->GetTargetInfo();
			if( target )
			{
				/// 타겟이 none이면 기본으로 hero를 타겟으로 세팅
				msg.targetType = ( target->type == eOBJECTTYPE_NONE )? HERO->GetObjectType() : target->type;
				msg.targetIndex = ( target->type == eOBJECTTYPE_NONE )? HERO->GetObjectID() : target->index;

				msg.number = (unsigned short)slotIndex;
				NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

				/// 잠금
				LockAndBackup( ITEM_TRY_USE, slotIndex );
			}
		}
		break;
	case ITEM_MATERIAL:
		if( subType == ITEM_MATERIAL_MAP )
		{
			cItemAbility* abil = itemDefine->GetAbililty();
			if( abil == 0 )
			{
				assert(0);
				return false;
			}
			HERO->UseMapChangeSkill( abil->GetInfluenceIndex(), slotIndex );
		}
		else if( subType == ITEM_MATERIAL_VEHICLE )
		{
			cItemAbility* abil = itemDefine->GetAbililty();
			if( abil == 0 )
			{
				assert(0);
				return false;
			}
			HERO->UseVehicleSkill( abil->GetInfluenceIndex(), slotIndex );
		}
		break;
	case ITEM_CARD:
		if( subType == ITEM_CARD_COMMON )	/// 소모용 카드이면 사용
		{
			/// 사용
			MSG_REQ_ITEM_USE_INVENTORY msg;
			::memset( &msg, 0, sizeof( msg ) );

			msg.Category    = NM_ITEM;
			msg.Protocol    = NM_ITEM_USE_INVENTORY_REQ;

			const sObject* target = HERO->GetTargetInfo();
			if( target )
			{
				/// 타겟이 none이면 기본으로 hero를 타겟으로 세팅
				msg.targetType = ( target->type == eOBJECTTYPE_NONE )? HERO->GetObjectType() : target->type;
				msg.targetIndex = ( target->type == eOBJECTTYPE_NONE )? HERO->GetObjectID() : target->index;

				msg.number = (unsigned short)slotIndex;
				NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

				/// 잠금
				LockAndBackup( ITEM_TRY_USE, slotIndex );
			}
		}
		if( subType == ITEM_CARD_EQUIP_C )	/// 캐릭터 장착용 카드면
		{
			MSG_REQ_ITEM_MOV_INVENTORY msg;
			::memset( &msg, 0, sizeof( msg ) );

			msg.Category = NM_ITEM;
			msg.Protocol = NM_ITEM_MOV_INVENTORY_REQ;
			msg.number1 = (unsigned short)slotIndex;
			msg.number2 = (unsigned short)i1;

			NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

			/// 잠금
			LockAndBackup( ITEM_TRY_EQUIP, slotIndex, i1 );
		}
		break;
	}
	return true;
}

/// 장착->인벤
bool cItemManager::TryToUnEquipItem( unsigned int slotIndex )
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	/// 탈착
	unsigned int slotIndex1 = 0;

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

	MSG_REQ_ITEM_MOV_INVENTORY msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_MOV_INVENTORY_REQ;
	msg.number1 = (unsigned short)slotIndex;
	msg.number2 = (unsigned short)slotIndex1;

	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 잠금
	LockAndBackup( ITEM_TRY_UNEQUIP, slotIndex );
	return true;
}

bool cItemManager::TryToDumpItem( unsigned int slotIndex )
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	/// 네트워크 메시지 전송
	MSG_REQ_ITEM_DEL_INVENTORY msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_DEL_INVENTORY_REQ;
	msg.number = (unsigned short)slotIndex;

	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 잠금
	LockAndBackup( ITEM_TRY_DUMP, slotIndex );
	return true;
}

bool cItemManager::TryToSplitItem( unsigned int slotIndex0, unsigned int slotIndex1, unsigned short value )
{
	if( value == 0 )
		return false;

	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	eItemIn in0 = GetItemIn( slotIndex0 );
	eItemIn in1 = GetItemIn( slotIndex1 );

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

	cItem& item0 = mItemArray[slotIndex0];
	cItem& item1 = mItemArray[slotIndex1];

	if( item0.mCount <= 1 || item0.mCount <= value )
		return false;

	if( item1.mCount )
		return false;

	cItemDefine* itemDefine = item0.mDefine;
	unsigned short capacity = itemDefine->mCapacity;

	if( value > capacity || item1.mCount >= capacity )
		return false;

	/// 인벤 개인 -> 인벤 개인
	if( in0 == ITEM_IN_INVEN_PRIVATE && in0 == in1 )
	{
		/// 걍 넘어감
	}
	/// 인벤 개인 <-> 창고 개인
	else if( (in0 == ITEM_IN_INVEN_PRIVATE && in1 == ITEM_IN_WAREHOUSE_PRIVATE) ||
		(in0 == ITEM_IN_WAREHOUSE_PRIVATE && in1 == ITEM_IN_INVEN_PRIVATE) )
	{
		if( item1.mCount )
			return false;

		/// 창고 -> 인벤
		if( in0 == ITEM_IN_WAREHOUSE_PRIVATE && in1 == ITEM_IN_INVEN_PRIVATE )
		{
			if( CheckMoveItem( item0.mIndex, value ) == false )
				return false;
		}
	}
	else
	{
		return false;
	}

	/// 네트워크 메시지 전송
	/// 인벤 개인 -> 인벤 개인
	if( in0 == ITEM_IN_INVEN_PRIVATE && in0 == in1 )
	{
		if( item0.mCount == 0 )
		{
			MSG_REQ_ITEM_MOV_INVENTORY msg;
			::memset( &msg, 0, sizeof( msg ) );

			msg.Category = NM_ITEM;
			msg.Protocol = NM_ITEM_MOV_INVENTORY_REQ;
			msg.number1 = (unsigned short)slotIndex0;
			msg.number2 = (unsigned short)slotIndex1;

			NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
		}
		else
		{
			MSG_REQ_ITEM_DIVIDE_INVENTORY msg;
			::memset( &msg, 0, sizeof( msg ) );

			msg.Category = NM_ITEM;
			msg.Protocol = NM_ITEM_DIVIDE_INVENTORY_REQ;
			msg.number1 = (unsigned short)slotIndex0;
			msg.number2 = (unsigned short)slotIndex1;
			msg.divide = value;

			NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
		}
	}
	/// 인벤 개인 <-> 창고 개인
	else if( (in0 == ITEM_IN_INVEN_PRIVATE && in1 == ITEM_IN_WAREHOUSE_PRIVATE) ||
		(in0 == ITEM_IN_WAREHOUSE_PRIVATE && in1 == ITEM_IN_INVEN_PRIVATE) )
	{
		MSG_REQ_NPC_ITEM_MOV2_INVENTORY msg;
		::memset( &msg, 0, sizeof( msg ) );

		msg.Category = NM_NPC;
		msg.Protocol = NM_NPC_ITEM_MOV2_INVENTORY_REQ;
		msg.npcIdx = HERO->GetNpcIdx();
		msg.number1 = (unsigned short)slotIndex0;
		msg.number2 = (unsigned short)slotIndex1;
		msg.count = value;

		NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
	}
	else
	{
		assert( 0 );
		return false;
	}

	/// 잠금
	LockAndBackup( ITEM_TRY_SPLIT, slotIndex0, slotIndex1, 0, value );
	return true;
}

bool cItemManager::TryToSwitchWeapon()
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}
	
	/// 무기 스위칭시 툴팁 제거
	UIMAN->HideTip();

	/// 네트워크 메시지 전송
	MSG_REQ_ITEM_SWI_INVENTORY msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_SWI_INVENTORY_REQ;

	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 잠금
	LockAndBackup( ITEM_TRY_SWITCH, 0 );
	return true;
}

/// 아이템 사기
bool cItemManager::TryToBuyItem( unsigned int itemIndex, unsigned short count )
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}
	
	if( count == 0 )
	{
		UIMAN->CreateModal(	eStage_Game,
							eMBEVENT_NONE, 
							GAMERESOURCEMAN->GetGameText( 232 ),	
							GAMERESOURCEMAN->GetGameText( 301 ),	 // 에러
							eSKIN_OK
							);
		return false;
	}

	if( CheckBuyItem( itemIndex, count ) == false )
		return false;

	/// 네트워크 메시지 전송
	MSG_REQ_NPC_ITEM_BUY msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category = NM_NPC;
	msg.Protocol = NM_NPC_ITEM_BUY_REQ;
	msg.npcIdx = HERO->GetNpcIdx();
	msg.itemDefineIndex = itemIndex;
	msg.count = count;

	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 잠금
	LockAndBackup( ITEM_TRY_BUY, 0 );

	cUIWindow* store = (cUIWindow*)GAMEUI->GetNpcStore();
	if( store )
		store->NetLock();

	return true;
}

/// 아이템 줍기
bool cItemManager::TryToGetItem(unsigned long itemIndex, unsigned short count)
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	bool FullWeight = false;

	/// 전부습득일경우.
	if( itemIndex == (unsigned long)ITEM_GET_ALL )
	{
		cLootingWindow* pLoot = GAMEUI->GetLootingWindow();
		if( pLoot )
		{
			/// 무게 검사
			float wei = mCurWeight + pLoot->GetWeight();
			if( wei > mMaxWeight )
				FullWeight = true;
		}
	}
	else
	{
		/// 개별 습득일경우
		cItemDefine* define = GetItemDefine( itemIndex );
		if( define && count > 0 )
		{
			/// 무게 검사
			float wei = mCurWeight + (define->GetWeight() * count);
			if( wei > mMaxWeight )
				FullWeight = true;
		}
	}

	if( FullWeight == true )
	{
		/// 무게게이지 풀
		UIMAN->CreateModal(	eStage_Game,
							eMBEVENT_NONE, 
							GAMERESOURCEMAN->GetGameText( 208 ),	// 무게게이지 풀
							GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
							eSKIN_OK
							);
		return false;
	}
	
	MSG_REQ_ITEM_GET msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_GET_REQ;
	msg.itemIndexOrInd = itemIndex;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 잠금
	//LockAndBackup( ITEM_TRY_GET, 0, 0, itemIndex );
	LockAndBackup( ITEM_TRY_GET, 0 );

	cLootingWindow* looting = GAMEUI->GetLootingWindow();
	if( looting )
		looting->NetLock( eLOCK_GETITEM );
	return true;
}


bool cItemManager::TryToSellItem( unsigned int slotIndex, unsigned short count )
{
	if( IsLocked() )
		return false;
	
	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	if( count == 0 )
	{
		UIMAN->CreateModal(	eStage_Game,
							eMBEVENT_NONE, 
							GAMERESOURCEMAN->GetGameText( 233 ),	
							GAMERESOURCEMAN->GetGameText( 301 ),	 // 에러
							eSKIN_OK
							);
		return false;
	}

	/// 판매조건 검사
	cItem& item = mItemArray[slotIndex];
	cItemDefine* itemDefine = item.mDefine;
	if( itemDefine == 0 )
	{
		assert(0);
		return false;
	}

	/// 퀘스트 용이면 무시
	if( itemDefine->GetType() == ITEM_QUEST )
		return false;

	if( itemDefine->GetSellType() == ItemSellNone )
		return false;

	/// 코인 획득시의 무게 측정 검사
	if( itemDefine->GetSellType() > ItemSellTarot )
	{
		cItemDefine* coinDefine = GetItemDefine( itemDefine->GetSellType() );
		if( coinDefine )
		{
			/// 기존무게 + 코인 무게 - 팔려는 아이템 무게
			float weight = (float)(coinDefine->GetWeight() * itemDefine->GetSellPrice()) + mCurWeight;
			weight -= ( itemDefine->GetWeight() * count );

			if( weight > mMaxWeight )
			{
				/// 무게게이지 풀
				UIMAN->CreateModal(	eStage_Game,
					eMBEVENT_NONE, 
					GAMERESOURCEMAN->GetGameText( 201 ),	// 무게게이지 풀
					GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
					eSKIN_OK
					);
				return false;
			}
		}
		else
		{
			assert(0);
			return false;
		}
	}

	/// 네트워크 메시지 전송
	MSG_REQ_NPC_ITEM_SELL msg;
	::memset( &msg, 0, sizeof( msg ) );

	msg.Category        = NM_NPC;
	msg.Protocol        = NM_NPC_ITEM_SELL_REQ;
	msg.npcIdx			= HERO->GetNpcIdx();
	msg.inventoryNumber = (unsigned short)slotIndex;
	msg.count           = count;

	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 잠금
	LockAndBackup( ITEM_TRY_SELL, slotIndex, 0, 0, count );
	return true;
}

/// 아이템 분해
bool cItemManager::TryToDisjoint( unsigned int slotIndex )
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	MSG_REQ_ITEM_DISJOINT_INVENTORY msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_DISJOINT_INVENTORY_REQ;
	msg.number = slotIndex;

	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 인벤토리 락
	LockAndBackup( ITEM_TRY_DISJOINT, slotIndex );
	return true;
}

bool cItemManager::TryToEnhancedStart()
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetState() == eOBJECT_STATE_STOP )
	{
		UIMAN->CreateModal(	eStage_Game,
			eMBEVENT_NONE, 
			GAMERESOURCEMAN->GetGameText( 235 ),
			GAMERESOURCEMAN->GetGameText( 301 ),
			eSKIN_OK
			);
		return false;
	}
	
	MSGROOT msg;
	::memset( &msg, 0, sizeof(msg) );
	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_ENHANCED_START_REQ;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	LockAndBackup( ITEM_TRY_ENHANCEDSTART, 0, 0 );

	cEnhancedWindow* win = GAMEUI->GetEnhancedWindow();
	if( win )
		win->NetLock();

	return true;
}

void cItemManager::TryToEnhancedCancel( bool close )
{
	if( HERO->GetStopFlag() == eSTOP_ENHANCED )
	{
		if( IsLocked() )
			return;

		MSGROOT msg;
		::memset( &msg, 0, sizeof(msg) );
		msg.Category = NM_ITEM;
		msg.Protocol = NM_ITEM_ENHANCED_CANCEL_REQ;
		NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

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

	cEnhancedWindow* win = GAMEUI->GetEnhancedWindow();
	if( win )
	{
		win->StopGauge();

		if( close == true )
			win->Hide();
	}
}

/// 아이템 강화
bool cItemManager::TryToEnhanced( unsigned int slotIndex0, unsigned int slotIndex1 )
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE )
	{
		UIMAN->CreateModal(	eStage_Game,
							eMBEVENT_NONE, 
							GAMERESOURCEMAN->GetGameText( 235 ),
							GAMERESOURCEMAN->GetGameText( 301 ),
							eSKIN_OK
							);
		return false;
	}

	///
	MSG_REQ_ITEM_ENHANCED_END msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_ENHANCED_END_REQ;
	msg.number1 = slotIndex0;
	msg.number2 = slotIndex1;

	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	LockAndBackup( ITEM_TRY_ENHANCEDEND, 0, 0 );

	cEnhancedWindow* win = GAMEUI->GetEnhancedWindow();
	if( win )
		win->NetLock();
	return true;
}

/// 네트워크
bool cItemManager::TryToTradeAsk( cPlayer* player )
{
	if( IsLocked() )
		return false;

	if( player == 0 )
		return false;

	/// 상태검사
	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}
		
	/// 저장
	mTradeTarget = player->GetObjectID();
	mTradeName = player->GetName();

	MSG_REQ_ITEM_EXCHANGE_ASK msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_ASK_REQ;
	msg.mTarget.index = player->GetObjectID();
	msg.mTarget.type = player->GetObjectType();
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
	return true;
}

/// 승인
void cItemManager::TryToTradeAccept()
{
	if( IsLocked() )
		return;

	/// 상태검사
	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	MSG_REQ_ITEM_EXCHANGE_REP msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_REP_REQ;
	msg.type = TYPE_ITEM_EXCHANGE_REP_ACCEPT;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
}

/// 거절
void cItemManager::TryToTradeReject()
{
	if( IsLocked() )
		return;

	/// 상태검사
	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	MSG_REQ_ITEM_EXCHANGE_REP msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_REP_REQ;
	msg.type = TYPE_ITEM_EXCHANGE_REP_REJECT;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
}

/// 아이템 등록
bool cItemManager::TryToTradeItemAdd( unsigned int slotIndex )
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	/// 거래불가 아이템인지 검사
	cItem& item = mItemArray[slotIndex];
	if( item.mDefine )
	{
		if( item.mDefine->GetExchange() != 0 )
		{
			CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 2019 ) );
			return false;
		}
	}
	else
	{
		assert(0);
		return false;
	}

	///
	MSG_REQ_ITEM_EXCHANGE_ADD msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_ADD_REQ;
	msg.type = TYPE_ITEM_EXCHANGE_ADD_ITEM;
	msg.number = slotIndex;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 락
	LockAndBackup( ITEM_TRY_TRADEADD, slotIndex );

	cUIWindow* trade = (cUIWindow*)GAMEUI->GetTradeWindow();
	if( trade )
		trade->NetLock();
	return true;
}

/// 금액 등록
bool cItemManager::TryToTradeMoneyAdd( unsigned long money )
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	mTradeMoney = money;

	MSG_REQ_ITEM_EXCHANGE_ADD msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_ADD_REQ;
	msg.type = TYPE_ITEM_EXCHANGE_ADD_MONEY;
	msg.money = money;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
	return true;
}

/// 아이템 삭제
bool cItemManager::TryToTradeItemDelete( unsigned int slotIndex, unsigned int arrIndex )
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	///
	MSG_REQ_ITEM_EXCHANGE_DEL msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_DEL_REQ;
	msg.number = slotIndex;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 락
	LockAndBackup( ITEM_TRY_TRADEDELETE, 0, 0, arrIndex );

	cUIWindow* trade = (cUIWindow*)GAMEUI->GetTradeWindow();
	if( trade )
		trade->NetLock();
	return true;
}

/// 거래 물품 확인 요청
void cItemManager::TryToTradeOk()
{
	if( IsLocked() )
		return;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	MSG_REQ_ITEM_EXCHANGE_OK msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_OK_REQ;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	cUIWindow* trade = (cUIWindow*)GAMEUI->GetTradeWindow();
	if( trade )
		trade->NetLock();
}

/// 거래 물품 수정요청
void cItemManager::TryToTradeReTry()
{
	if( IsLocked() )
		return;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	MSG_REQ_ITEM_EXCHANGE_RETRY msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_RETRY_REQ;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	cUIWindow* trade = (cUIWindow*)GAMEUI->GetTradeWindow();
	if( trade )
		trade->NetLock();
}

/// 닫기요청
void cItemManager::TryToTradeCancel()
{
	if( IsLocked() )
		return;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	MSG_REQ_ITEM_EXCHANGE_CANCEL msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_CANCEL_REQ;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	cUIWindow* trade = (cUIWindow*)GAMEUI->GetTradeWindow();
	if( trade )
		trade->NetLock();
}

/// 거래 종료
void cItemManager::TryToTradeEnd()
{
	if( IsLocked() )
		return;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	MSG_REQ_ITEM_EXCHANGE_END msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_EXCHANGE_END_REQ;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	cUIWindow* trade = (cUIWindow*)GAMEUI->GetTradeWindow();
	if( trade )
		trade->NetLock();
}

/// 노점열기 요청
bool cItemManager::TryToUserSellOpen()
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	/// 
	if( HERO->IsRideVehicle() == true )
	{
		MSGROOT msg;
		::memset( &msg, 0, sizeof(msg) );
		msg.Category = NM_PLAYER;
		msg.Protocol = NM_PLAYER_VEHICLE_END_REQ;
		NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

		HERO->AlightVehicle();
	}

	mUserSellName = GAMERESOURCEMAN->GetGameText( 2514 );

	MSG_REQ_ITEM_STALL_SELL_OPEN msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_OPEN_REQ;
	Sstrncpy( msg.title, MAX_STALL_TITLE_LEN, (LPCTSTR)mUserSellName.Cstr(), mUserSellName.GetLength() );
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	cUIWindow* sell = (cUIWindow*)GAMEUI->GetUserSellWindow();
	if( sell )
		sell->NetLock( eLOCK_REGIST );
	return true;
}

bool cItemManager::TryToUserSellReName( LPCTSTR title )
{
	if( IsLocked() )
		return false;

	int len = ::_tcslen(title);
	if( len == 0 )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	mUserSellName = title;

	MSG_REQ_ITEM_STALL_SELL_RENAME msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_RENAME_REQ;
	Sstrncpy( msg.title, MAX_STALL_TITLE_LEN, title, len );
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	cUIWindow* sell = (cUIWindow*)GAMEUI->GetUserSellWindow();
	if( sell )
		sell->NetLock( eLOCK_RENAME );
	return true;
}

/// 노점닫기 요청
void cItemManager::TryToUserSellClose()
{
	if( IsLocked() )
		return;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	MSG_REQ_ITEM_STALL_SELL_CLOSE msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_CLOSE_REQ;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	cUIWindow* sell = (cUIWindow*)GAMEUI->GetUserSellWindow();
	if( sell )
		sell->NetLock( eLOCK_END );
}

/// 노점 아이템 등록
bool cItemManager::TryToUserSellAdd( unsigned short slot, unsigned long price )
{
	if( IsLocked() == true )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	/// 거래불가 아이템 등록 막기
	cItem& item = mItemArray[slot];
	if( !item.mDefine )
	{
		assert(0);
		return false;
	}

	// 거래불가 아이템일경우
	if( item.mDefine->GetExchange() == 1 )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 247 ) );
		return false;
	}

	///
	MSG_REQ_ITEM_STALL_SELL_ADD msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_ADD_REQ;
	msg.number = slot;
	msg.price = price;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	/// 저장
	LockAndBackup( ITEM_TRY_SELLITEMADD, slot, 0, 0, 0, price );

	cUIWindow* sell = (cUIWindow*)GAMEUI->GetUserSellWindow();
	if( sell )
		sell->NetLock( eLOCK_ADD );
	return true;
}

/// 노점 아이템 삭제
bool cItemManager::TryToUserSellDelete( unsigned short slot )
{
	if( IsLocked() == true )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	cUIWindow* sell = (cUIWindow*)GAMEUI->GetUserSellWindow();
	if( sell->IsVisible() == false )
		return false;

	MSG_REQ_ITEM_STALL_SELL_DEL msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_DEL_REQ;
	msg.number = slot;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	LockAndBackup( ITEM_TRY_SELLITEMDELETE, slot );
	
	if( sell )
		sell->NetLock( eLOCK_DELETE );
	return true;
}

/// 노점 아이템 수정
bool cItemManager::TryToUserSellModify( unsigned short slot )
{
	if( IsLocked() )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	/// 락 걸려있으면 리턴
	cUIWindow* sell = (cUIWindow*)GAMEUI->GetUserSellWindow();
	if( sell && sell->IsNetLock() == true )
		return false;

	///
	MSG_REQ_ITEM_STALL_SELL_MOD msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_MOD_REQ;
	msg.number = slot;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
	
	if( sell )
		sell->NetLock( eLOCK_ITEMUPDATE );
	return true;
}

void cItemManager::TryToUserSellJoin( sObject& obj )
{
	if( IsLocked() )
		return;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	mUserSellTarget = obj.index;

	/// 노점상 열기 요청
	MSG_REQ_ITEM_STALL_SELL_JOIN msg;
	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_JOIN_REQ;
	msg.mTarget = obj;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
}

/// 노점상보기 닫기 요청
void cItemManager::TryToUserSellJoinClose()
{
	if( IsLocked() )
		return;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	MSG_REQ_ITEM_STALL_SELL_LEAVE msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_LEAVE_REQ;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	cUIWindow* sell = (cUIWindow*)GAMEUI->GetUserSellWindow();
	if( sell )
		sell->NetLock( eLOCK_JOINEND );
}

/// 노점 아이템 구입요청
bool cItemManager::TryToUserSellGet( unsigned short slot, unsigned short count )
{
	if( IsLocked() == true )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

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

	/// 사려고하는 아이템관련 체크
	sUserSellData* data = sell->GetSelectJoinData();
	sInventory* inv = &data->mThatInven;

	cItemDefine* define = GetItemDefine( inv->ItemIndex );
	if( define )
	{
		/// 무게 검사
		float wei = mCurWeight + (define->GetWeight() * count);
		if( wei > mMaxWeight )
		{
			/// 무게게이지 풀
			UIMAN->CreateModal(	eStage_Game,
								eMBEVENT_NONE, 
								GAMERESOURCEMAN->GetGameText( 201 ),	// 무게게이지 풀
								GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
								eSKIN_OK
								);
			return false;
		}

		/// 소지금 검사
		if( HERO->GetMoney() < data->mPrice )
		{
			UIMAN->CreateModal(	eStage_Game,
								eMBEVENT_NONE, 
								GAMERESOURCEMAN->GetGameText( 200 ),	// 소지금 부족
								GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
								eSKIN_OK
								);
			return false;
		}
	}


	MSG_REQ_ITEM_STALL_SELL_GET msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_GET_REQ;
	msg.number = slot;
	msg.count = count;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	LockAndBackup( ITEM_TRY_SELLGET, 0 );
	
	if( sell )
		sell->NetLock( eLOCK_GET );
	return true;
}

void cItemManager::TryToUserSellSearch( unsigned long itemIndex, unsigned char enhanced )
{
	if( IsLocked() )
		return;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return;
	}

	MSG_REQ_ITEM_STALL_SELL_SEARCH msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_STALL_SELL_SEARCH_REQ;
	msg.itemDefineIndex = itemIndex;
	msg.enhanced = enhanced;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	cUIWindow* search = (cUIWindow*)GAMEUI->GetUserSellSearchWindow();
	if( search )
		search->NetLock();
}

bool cItemManager::TryToPutCard( unsigned int itemSlot, unsigned int cardSlot, unsigned int putSlot )
{
	if( IsLocked() == true )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	MSG_REQ_ITEM_PUT_CARD_INVENTORY msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_PUT_CARD_INVENTORY_REQ;
	msg.number1 = itemSlot;
	msg.number2 = cardSlot;		/// 사용될 카드

	/// ( 0 ~ 5 까지 카드 삽입 슬롯 지정 )
	msg.cardSlot = putSlot;
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	//LockAndBackup( ITEM_TRY_PUTCARD, 0, 0, cardSlot );
	LockAndBackup( ITEM_TRY_PUTCARD, cardSlot );

	cUIWindow* putcard = (cUIWindow*)GAMEUI->GetPutCardWindow();
	if( putcard )
		putcard->NetLock();

	return true;
}

/// 컬렉션북 등록
bool cItemManager::TryToCardBookAdd( unsigned int slot0, unsigned int slot1 )
{
	if( IsLocked() == true )
		return false;

	if( HERO->GetState() == eOBJECT_STATE_DIE || HERO->GetStopFlag() == eSTOP_ITEMMIX )
	{
		CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 235 ) );
		return false;
	}

	MSG_REQ_ITEM_COLLECT msg;
	::memset( &msg, 0, sizeof(msg) );

	msg.Category = NM_ITEM;
	msg.Protocol = NM_ITEM_COLLECT_REQ;
	msg.number1 = slot0;
	msg.number2 = slot1;		/// 사용될 카드
	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );

	LockAndBackup( ITEM_TRY_CARDBOOKADD, slot0, slot1 );
	return true;
}

void cItemManager::NpcNetTryItem( unsigned int protocol, void* msg )
{
	switch( protocol )
	{
	case NM_NPC_ITEM_MOV2_INVENTORY_RES:
		NetTryItem( protocol, msg );
		break;

	case NM_NPC_ITEM_BUY_RES:
		NetTryItem( protocol, msg );
		break;

	case NM_NPC_ITEM_SELL_RES:
		NetTryItem( protocol, msg );
		break;

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

void cItemManager::LockAndBackup(eItemTry itemTry, unsigned int slotIndex0, unsigned int slotIndex1, 
								 unsigned long tempItemIndex, unsigned short value, unsigned long price, cItemIcon* icon )
{
	mLocked = true;
	mTry = itemTry;

	mSlotIndex0 = slotIndex0;
	mSlotIndex1 = slotIndex1;
	mTempIndex = tempItemIndex;
	mValue = value;
	mPrice = price;
}

bool cItemManager::IsLocked()
{
	if( mLocked )
		return true;

	return UIMAN->IsVisibleDrag();
}

/// 백업 데이터 빼고, try만 저장함
void cItemManager::LockItemTry( eItemTry itemTry, unsigned long slotIndex0 )
{
	mLocked = true;
	mTry = itemTry;
	mSlotIndex0 = slotIndex0;
	mSlotIndex1 = 0;
	mValue = 0;
	mTempIndex = 0;
}

/// 풀어도 되는 락인지 검사후 unlock
void cItemManager::UnlockItemTry( eItemTry itemTry )
{
	if( mTry == itemTry )
	{
		mLocked = false;
		mTry = ITEM_TRY_NULL;

		if( mSlotIndex0 < MAX_INVENTORY )
		{
			cItem& item0 = mItemArray[mSlotIndex0];
			if( item0.GetIcon() )
				item0.SetUsedFlag( true );
		}
	
		if( mSlotIndex1 < MAX_INVENTORY )
		{
			cItem& item1 = mItemArray[mSlotIndex1];
			if( item1.GetIcon() )
				item1.SetUsedFlag( true );
		}

		mSlotIndex0 = 0;
		mSlotIndex1 = 0;
		mValue = 0;
	}
	else
	{
		assert(0);
	}
}

void cItemManager::CheckItemSlot( unsigned int slotIndex )
{
	switch( slotIndex )
	{
	case INVENTORY_HAND_LEFT1:
	case INVENTORY_HAND_RIGHT1:
		{
			cItem& lItem = mItemArray[INVENTORY_HAND_LEFT1];
			cItem& rItem = mItemArray[INVENTORY_HAND_RIGHT1];

			if( lItem.mCount == 0 )
				lItem = 0;
			if( rItem.mEquipType == ITEM_EQUIP_TWO_HANDS )
				lItem.SetTwoHanded( true, rItem.mIcon ? rItem.mIcon->GetIconParam() : 0, rItem.mDefine );
			else
				lItem.SetTwoHanded( false );
		}
		break;
	case INVENTORY_HAND_LEFT2:
	case INVENTORY_HAND_RIGHT2:
		{
			cItem& lItem = mItemArray[INVENTORY_HAND_LEFT2];
			cItem& rItem = mItemArray[INVENTORY_HAND_RIGHT2];

			if( lItem.mCount == 0 )
				lItem = 0;
			if( rItem.mEquipType == ITEM_EQUIP_TWO_HANDS )
				lItem.SetTwoHanded( true, rItem.mIcon ? rItem.mIcon->GetIconParam() : 0, rItem.mDefine );
			else
				lItem.SetTwoHanded( false );
		}
		break;
	}
}

void cItemManager::ClearAbility()
{
	::memset( &mBasicAbil, 0, sizeof(sEquipAbility) );
}

void cItemManager::AddSpecialAbility( short type, short value )
{
	#define Warning4244(V,A) V = V + A

	switch ( type )
	{
	case ITEM_OPT_STR:	// 힘
		Warning4244( mBasicAbil.mOptStr, value );
		break;
	case ITEM_OPT_DEX:	// 민첩
		Warning4244( mBasicAbil.mOptDex, value );
		break;
	case ITEM_OPT_CON:	// 체력
		Warning4244( mBasicAbil.mOptCon, value );
		break;
	case ITEM_OPT_INT:	// 지능
		Warning4244( mBasicAbil.mOptInt, value );
		break;
	case ITEM_OPT_WIS:	// 지혜
		Warning4244( mBasicAbil.mOptWis, value );
		break;
	case ITEM_OPT_ALL:	// 모두(힘:민첩:체력:지능:지혜)
		Warning4244( mBasicAbil.mOptStr, value );
		Warning4244( mBasicAbil.mOptDex, value );
		Warning4244( mBasicAbil.mOptCon, value );
		Warning4244( mBasicAbil.mOptInt, value );
		Warning4244( mBasicAbil.mOptWis, value );
		break;

		// Option - Plus
	case ITEM_OPT_PLUS_PHYSIC_ATTACK:	// 물리공격력
		Warning4244( mBasicAbil.mOptPlusPhysicAttack, value );
		break;
	case ITEM_OPT_PLUS_MAGIC_ATTACK:	// 마법공격력
		Warning4244( mBasicAbil.mOptPlusMagicAttack, value );
		break;
	case ITEM_OPT_PLUS_PHYSIC_DEFENSE:	// 물리방어력
		Warning4244( mBasicAbil.mOptPlusPhysicDefense, value );
		break;
	case ITEM_OPT_PLUS_MAGIC_DEFENSE:	// 마법방어력
		Warning4244( mBasicAbil.mOptPlusMagicDefense, value );
		break;
	case ITEM_OPT_PLUS_PHYSIC_ATTACK_RATE:	// 물리명중률
		Warning4244( mBasicAbil.mOptPlusPhysicAttackRate, value );
		break;
	case ITEM_OPT_PLUS_MAGIC_ATTACK_RATE:	// 마법명중률
		Warning4244( mBasicAbil.mOptPlusMagicAttack, value );
		break;
	case ITEM_OPT_PLUS_PHYSIC_CRITICAL:	// 물리크리티컬
		Warning4244( mBasicAbil.mOptPlusPhysicCritical, value );
		break;
	case ITEM_OPT_PLUS_MAGIC_CRITICAL:	// 마법크리티컬
		Warning4244( mBasicAbil.mOptPlusMagicCritical, value );
		break;
	case ITEM_OPT_PLUS_DOD:	// 회피
		Warning4244( mBasicAbil.mOptPlusDod, value );
		break;
	case ITEM_OPT_PLUS_WEI:	// 무게
		Warning4244( mBasicAbil.mOptPlusWei, value );
		break;
	case ITEM_OPT_PLUS_MAX_HP:	// 최대량 HP
		Warning4244( mBasicAbil.mOptPlusMaxHp, value );
		break;
	case ITEM_OPT_PLUS_MAX_MP:	// 최대량 MP
		Warning4244( mBasicAbil.mOptPlusMaxMp, value );
		break;
	case ITEM_OPT_PLUS_MOV:	// 이동
		Warning4244( mBasicAbil.mOptPlusMov, value );
		break;
	case ITEM_OPT_PLUS_HP:	// HP 회복
		Warning4244( mBasicAbil.mOptPlusHp, value );
		break;
	case ITEM_OPT_PLUS_MP:	// MP 회복
		Warning4244( mBasicAbil.mOptPlusMp, value );
		break;

		// Option - Percent
	case ITEM_OPT_PERCENT_PHYSIC_ATTACK:	// 물리공격력
		Warning4244( mBasicAbil.mOptPercentPhysicAttack, value );
		break;
	case ITEM_OPT_PERCENT_MAGIC_ATTACK:	// 마법공격력
		Warning4244( mBasicAbil.mOptPercentMagicAttack, value );
		break;
	case ITEM_OPT_PERCENT_PHYSIC_DEFENSE:	// 물리방어력
		Warning4244( mBasicAbil.mOptPercentPhysicDefense, value );
		break;
	case ITEM_OPT_PERCENT_MAGIC_DEFENSE:	// 마법방어력
		Warning4244( mBasicAbil.mOptPercentMagicDefense, value );
		break;
	case ITEM_OPT_PERCENT_PHYSIC_ATTACK_RATE:	// 물리명중률
		Warning4244( mBasicAbil.mOptPercentPhysicAttackRate, value );
		break;
	case ITEM_OPT_PERCENT_MAGIC_ATTACK_RATE:	// 마법명중률
		Warning4244( mBasicAbil.mOptPercentMagicAttack, value );
		break;
	case ITEM_OPT_PERCENT_PHYSIC_CRITICAL:	// 물리크리티컬
		Warning4244( mBasicAbil.mOptPercentPhysicCritical, value );
		break;
	case ITEM_OPT_PERCENT_MAGIC_CRITICAL:	// 마법크리티컬
		Warning4244( mBasicAbil.mOptPercentMagicCritical, value );
		break;
	case ITEM_OPT_PERCENT_DOD:	// 회피
		Warning4244( mBasicAbil.mOptPercentDod, value );
		break;
	case ITEM_OPT_PERCENT_WEI:	// 무게
		Warning4244( mBasicAbil.mOptPercentWei, value );
		break;
	case ITEM_OPT_PERCENT_MAX_HP:	// 최대량 HP
		Warning4244( mBasicAbil.mOptPercentMaxHp, value );
		break;
	case ITEM_OPT_PERCENT_MAX_MP:	// 최대량 MP
		Warning4244( mBasicAbil.mOptPercentMaxMp, value );
		break;
	case ITEM_OPT_PERCENT_MOV:	// 이동
		Warning4244( mBasicAbil.mOptPercentMov, value );
		break;
	case ITEM_OPT_PERCENT_HP:	// HP 회복
		Warning4244( mBasicAbil.mOptPercentHp, value );
		break;
	case ITEM_OPT_PERCENT_MP:	// MP 회복
		Warning4244( mBasicAbil.mOptPercentMp, value );
		break;

		// Option - Etc
	case ITEM_OPT_PERCENT_DRAIN_HP:				// HP 흡수
		Warning4244( mBasicAbil.mOptPercentDrainHp, value );
		break;
	case ITEM_OPT_PERCENT_DRAIN_MP:				// MP 흡수
		Warning4244( mBasicAbil.mOptPercentDrainMp, value );
		break;
	case ITEM_OPT_PERCENT_SKILL_HEAL_INC:		// 스킬 힐 회복량 증가
		Warning4244( mBasicAbil.mOptPercentSkillHealInc, value );
		break;
	case ITEM_OPT_PERCENT_DAMAGE_DEC:			// 데미지 흡수/감소
		Warning4244( mBasicAbil.mOptPercentDamageDec, value );
		break;
	case ITEM_OPT_PERCENT_DAMAGE_REF:			// 데미지 반사
		Warning4244( mBasicAbil.mOptPercentDamageRef, value );
		break;
	}
}

/// 아이템 어빌리티 계산
void cItemManager::AddAbility( cItem& item )
{
	cItemDefine* define = item.mDefine;
	if( !define )
	{
		assert(0);
		return;
	}

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

	cItemAbility* abil = define->GetAbililty();
	if( !abil )
	{
		assert(0);
		return;
	}

	/// 기본수치
	mBasicAbil.mPhysicMinAttack	= mBasicAbil.mPhysicMinAttack + abil->GetPhysicMinAttack();	/// 물리:최소공격력
	mBasicAbil.mPhysicMaxAttack = mBasicAbil.mPhysicMaxAttack + abil->GetPhysicMaxAttack();	/// 물리:최대공격력
	mBasicAbil.mMagicMinAttack	= mBasicAbil.mMagicMinAttack  + abil->GetMagicMinAttack();	/// 마법:최소공격력
	mBasicAbil.mMagicMaxAttack	= mBasicAbil.mMagicMaxAttack  + abil->GetMagicMaxAttack();	/// 마법:최대공격력

	mBasicAbil.mPhysicDefense	= mBasicAbil.mPhysicDefense   + abil->GetPhysicDefense();	/// 물리:방어력
	mBasicAbil.mMagicDefense	= mBasicAbil.mMagicDefense    + abil->GetMagicDefense();	/// 마법:방어력
	mBasicAbil.mAttackRange		= mBasicAbil.mAttackRange     + abil->GetAttackRange();		/// 공격 거리
	mBasicAbil.mAttackSpeed		= mBasicAbil.mAttackSpeed     + abil->GetAttackSpeed();		/// 공격 속도

	/// 옵션 값
	sAblityOption* opt = abil->GetOption();
	for( int i = 0; i < 10; ++i, ++opt )
	{
		AddSpecialAbility( opt->mOptType, opt->mOptValue );
	}
			
	/// 무기, 방어구
	if( type == ITEM_WEAPON || type == ITEM_WEAR )
	{
		/// 강화된 아이템의 수치 합하기
		AddEnhance( item );

		/// 아이템 장착카드 수치 합하기
		AddPutCard( item.mCardIndex1 );
		AddPutCard( item.mCardIndex2 );
		AddPutCard( item.mCardIndex3 );
		AddPutCard( item.mCardIndex4 );
		AddPutCard( item.mCardIndex5 );
	}
}

/// 강화정보 체크
void cItemManager::AddEnhance( cItem& item )
{
	cItemDefine* define = item.mDefine;
	if( !define )
	{
		assert(0);
		return;
	}

	unsigned char enhanceStep = item.GetEnhanceStep();
	if( enhanceStep > 0 )
	{
		/// 강화단계에 따른 + 수치 출력
		short addPhysicAttack = 0;
		short addMagicAttack = 0;
		short addPhysicDefense = 0;
		short addMagicDefense = 0;

		sItemEnhanced* enhance = define->GetEnhanced();
		if( !enhance )
		{
			assert(0);
			return;
		}

		/// 물리공격력 세팅
		if( enhance->mEnhanced1 == eENHANCE_PHYSICATTACK || 
			enhance->mEnhanced2 == eENHANCE_PHYSICATTACK )
		{
			addPhysicAttack = enhance->mValue[enhanceStep-1];

			mBasicAbil.mPhysicMinAttack	= mBasicAbil.mPhysicMinAttack + addPhysicAttack;	/// 물리:최소공격력
			mBasicAbil.mPhysicMaxAttack = mBasicAbil.mPhysicMaxAttack + addPhysicAttack;	/// 물리:최대공격력
		}

		/// 마법공격력 수치 & 세팅
		if( enhance->mEnhanced1 == eENHANCE_MAGICATTACK || 
			enhance->mEnhanced2 == eENHANCE_MAGICATTACK )
		{
			addMagicAttack = enhance->mValue[enhanceStep-1];

			mBasicAbil.mMagicMinAttack	= mBasicAbil.mMagicMinAttack + addMagicAttack;	/// 마법:최소공격력
			mBasicAbil.mMagicMaxAttack	= mBasicAbil.mMagicMaxAttack + addMagicAttack;	/// 마법:최대공격력
		}

		/// 물리 방어력 세팅 
		if( enhance->mEnhanced1 == eENHANCE_PHYSICDEFENSE || 
			enhance->mEnhanced2 == eENHANCE_PHYSICDEFENSE )
		{
			addPhysicDefense = enhance->mValue[enhanceStep-1];
			mBasicAbil.mPhysicDefense	= mBasicAbil.mPhysicDefense + addPhysicDefense;		/// 물리:방어력
		}

		/// 마법 방어력 세팅 
		if( enhance->mEnhanced1 == eENHANCE_MAGICDEFENSE || 
			enhance->mEnhanced2 == eENHANCE_MAGICDEFENSE )
		{
			addMagicDefense = enhance->mValue[enhanceStep-1];
			mBasicAbil.mMagicDefense	= mBasicAbil.mMagicDefense + addMagicDefense;		/// 마법:방어력
		}

	}
}

/// 카드장착 정보 체크
void cItemManager::AddPutCard( unsigned long cardIndex )
{
	if( cardIndex == 0 )
		return;

	cItemDefine* cardDefine = GetItemDefine( cardIndex );
	if( !cardDefine )
	{
		assert(0);
		return;
	}

	cItemAbility* abil = cardDefine->GetAbililty();
	if( !abil )
	{
		assert(0);
		return;
	}

	/// 장착한 카드의 정보만큼 갱신
	mBasicAbil.mPhysicMinAttack	= mBasicAbil.mPhysicMinAttack + abil->GetPhysicMinAttack();	/// 물리:최소공격력
	mBasicAbil.mPhysicMaxAttack = mBasicAbil.mPhysicMaxAttack + abil->GetPhysicMaxAttack();	/// 물리:최대공격력
	mBasicAbil.mMagicMinAttack	= mBasicAbil.mMagicMinAttack  + abil->GetMagicMinAttack();	/// 마법:최소공격력
	mBasicAbil.mMagicMaxAttack	= mBasicAbil.mMagicMaxAttack  + abil->GetMagicMaxAttack();	/// 마법:최대공격력

	mBasicAbil.mPhysicDefense	= mBasicAbil.mPhysicDefense   + abil->GetPhysicDefense();	/// 물리:방어력
	mBasicAbil.mMagicDefense	= mBasicAbil.mMagicDefense    + abil->GetMagicDefense();	/// 마법:방어력
	mBasicAbil.mAttackRange		= mBasicAbil.mAttackRange     + abil->GetAttackRange();		/// 공격 거리
	mBasicAbil.mAttackSpeed		= mBasicAbil.mAttackSpeed     + abil->GetAttackSpeed();		/// 공격 속도

	/// 옵션 값
	sAblityOption* opt = abil->GetOption();
	for( int i = 0; i < 10; ++i, ++opt )
	{
		AddSpecialAbility( opt->mOptType, opt->mOptValue );
	}
}


void cItemManager::CheckEquipAbility()
{
	/// 정보 초기화
	ClearAbility();

	/// 무기제외
	for( unsigned int i = INVENTORY_WEAR_BEGIN; i <= INVENTORY_WEAR_CARD3; ++i )
	{
		cItem& item = mItemArray[i];
		if( item.mDefine )
			AddAbility( item );
	}

	/// 장착 무기류 검사
	if( mActiveWeapon == ItemActiveFront )
	{
		cItem& hLeft2 = mItemArray[INVENTORY_HAND_LEFT2];	/// 방패류 혹은 양손
		cItem& hRight2 = mItemArray[INVENTORY_HAND_RIGHT2];	/// 한손 혹은 양손

		/// 무기착용시
		if( hRight2.mDefine )
			AddAbility(  hRight2 );

		/// 방패착용시
		if( hLeft2.mDefine && hLeft2.mEquipType == ITEM_EQUIP_SHIELD )
			AddAbility( hLeft2 );
	}
	else
	{
		cItem& hLeft1 = mItemArray[INVENTORY_HAND_LEFT1];	/// 방패류 혹은 양손
		cItem& hRight1 = mItemArray[INVENTORY_HAND_RIGHT1];	/// 한손 혹은 양손

		/// 무기착용시
		if( hRight1.mDefine )
			AddAbility(  hRight1 );

		/// 방패착용시
		if( hLeft1.mDefine && hLeft1.mEquipType == ITEM_EQUIP_SHIELD )
			AddAbility( hLeft1 );
	}

	
	HERO->CalcStatus();
}

cItem& cItemManager::GetHeroRightWeapon()
{
	unsigned int slot = ( mActiveWeapon == ItemActiveFront ) ? INVENTORY_HAND_RIGHT2 : INVENTORY_HAND_RIGHT1;
	return mItemArray[slot];
//	cItem hRight = mItemArray[slot];
//	if( hRight.mDefine )
//		return hRight.mDefine->GetSubType();	
//	return -1;
}

cItem& cItemManager::GetHeroLeftWeapon()
{
	unsigned int slot = ( mActiveWeapon == ItemActiveFront ) ? INVENTORY_HAND_LEFT2 : INVENTORY_HAND_LEFT1;
	return mItemArray[slot];

//	cItem& hLeft = mItemArray[slot];
//	if( hLeft.mDefine )
//		return hLeft.mDefine->GetSubType();	
//	return -1;
}

bool cItemManager::IsEquipWeapon()
{
	cItem& rItem0 = mItemArray[INVENTORY_HAND_RIGHT1];
	cItem& rItem1 = mItemArray[INVENTORY_HAND_RIGHT2];
	cItem& lItem0 = mItemArray[INVENTORY_HAND_LEFT1];
	cItem& lItem1 = mItemArray[INVENTORY_HAND_LEFT2];

	if( rItem0.mCount > 0 || rItem1.mCount > 0 || lItem0.mCount > 0 || lItem1.mCount > 0 )
        return true;
	return false;
}

/// 아이템의 제약사항 검사
bool cItemManager::CheckLimit( unsigned int slotIndex )
{
	cItem& item = mItemArray[slotIndex];
	if( !item.mDefine )
		return true;

	cItemLimit* itemLimit = item.mDefine->GetLimit();
	if( itemLimit )
	{
		/// 레벨 검사
		if( HERO->GetLevel() < itemLimit->GetLevel() )
			return false;

		/// 성별검사
		if( itemLimit->GetGender() != ITEM_GENDER_ALL )
		{
			if( HERO->GetGender() != itemLimit->GetGender() )
				return false;
		}
		
		/// 직업
		if( itemLimit->GetJob() != ITEM_JOB_ALL )
		{
			long job = HERO->GetJob() - ( HERO->GetJob() % ITEM_JOB_FIGHTER );
			if( job != itemLimit->GetJob() )
				return false;
		}	

		/// 종족
		if( itemLimit->GetRace() != ITEM_RACE_ALL )
		{
			if( HERO->GetRace() != itemLimit->GetRace() )
				return false;
		}
	}
	return true;
}

/// 아이템 이동시 조건검사
bool cItemManager::CheckMoveItem(unsigned int itemIndex, unsigned short count)
{
	/// 슬롯 full 검사
	unsigned int slotIndex = 0;
	FindEmptySlot( &slotIndex, INVENTORY_BAG_BEGIN, INVENTORY_BAG_END );
	if( slotIndex == 0 )
	{
		/// 오류메시지 202
		UIMAN->CreateModal(	eStage_Game,
							eMBEVENT_NONE, 
							GAMERESOURCEMAN->GetGameText( 207 ),	// 슬롯 풀
							GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
							eSKIN_OK
							);
		return false;
	}

	cItemDefine* define = GetItemDefine( itemIndex );
	if( define )
	{
		/// 무게 검사
		float wei = mCurWeight + (define->GetWeight() * count);
		if( wei > mMaxWeight )
		{
			/// 무게게이지 풀
			UIMAN->CreateModal(	eStage_Game,
								eMBEVENT_NONE, 
								GAMERESOURCEMAN->GetGameText( 208 ),	// 무게게이지 풀
								GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
								eSKIN_OK
								);
			return false;
		}
	}
	return true;
}

/// 해당 아이템이 인벤에 들어갈수 있는 최대 수 구하기
int cItemManager::GetRemainCount( unsigned int itemIndex, unsigned short mincount )
{
	cItemDefine* define = GetItemDefine( itemIndex );
	if( !define )
		return -1;

	unsigned short capacity = define->GetCapacity();
	if( capacity == 0 )
	{
		assert(0);
		return -1;
	}

	unsigned int emptySlotCnt = 0;
	int itemCount = 0;
	for( unsigned int slot = INVENTORY_BAG0_BEGIN; slot <= INVENTORY_BAG3_END; ++slot )
	{
		/// 빈슬롯 검사
		cItem& item = mItemArray[slot];
		if( item.GetIndex() == 0 )
		{
			emptySlotCnt++;

			if( emptySlotCnt * capacity >= mincount )
				return mincount;
		}
		/// 겹치기 검사
		else if( item.GetIndex() == itemIndex )
		{
			unsigned int remainCnt = capacity - item.GetCount();
			itemCount = itemCount + remainCnt;
			if( itemCount >= mincount )
				return mincount;
		}

		unsigned int applyCnt = emptySlotCnt * capacity;
		if( itemCount + applyCnt >= mincount )
			return mincount;
	}

	itemCount += (emptySlotCnt * capacity);
	return itemCount;
}

bool cItemManager::CheckEmptySlot( unsigned int itemIndex, unsigned short count )
{
	cItemDefine* define = GetItemDefine( itemIndex );
	if( !define )
		return false;

	unsigned short capacity = define->GetCapacity();
	if( capacity == 0 )
	{
		assert(0);
		return false;
	}

	unsigned int emptySlotCnt = 0;
	short itemCount = count;
	for( unsigned int slot = INVENTORY_BAG0_BEGIN; slot <= INVENTORY_BAG3_END; ++slot )
	{
		/// 빈슬롯 검사
		cItem& item = mItemArray[slot];
		if( item.GetIndex() == 0 )
		{
			emptySlotCnt++;
		
			if( emptySlotCnt * capacity >= count )
				return true;
		}
		/// 겹치기 검사
		else if( item.GetIndex() == itemIndex )
		{
			unsigned int remainCnt = capacity - item.GetCount();
			itemCount = itemCount - remainCnt;
			if( itemCount <= 0 )
				return true;
		}

		unsigned int applyCnt = emptySlotCnt * capacity;
		if( itemCount - applyCnt <= 0 )
			return true;
	}
	return false;
}

/// 아이템 구입시 조건검사
bool cItemManager::CheckBuyItem(unsigned int itemIndex, unsigned short count)
{
	if( CheckEmptySlot( itemIndex, count ) == false )
	{
		UIMAN->CreateModal(	eStage_Game,
							eMBEVENT_NONE, 
							GAMERESOURCEMAN->GetGameText( 202 ),	// 공간 부족
							GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
							eSKIN_OK
							);
		return false;
	}

	cItemDefine* define = GetItemDefine( itemIndex );
	if( define )
	{
		/// 소지금 검사
		unsigned long price = define->GetBuyPrice() * count;
		switch( define->GetBuyType() )
		{
		case ItemBuyNone:
			{
				assert(0);
				return false;
			}
		case ItemBuyMoney:
			if( HERO->GetMoney() < price )
			{
				UIMAN->CreateModal(	eStage_Game,
					eMBEVENT_NONE, 
					GAMERESOURCEMAN->GetGameText( 200 ),	// 소지금 부족
					GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
					eSKIN_OK
					);
				return false;
			}
			break;
		case ItemBuyPvp:
			if( HERO->GetTarotPoint() < price )
			{
				UIMAN->CreateModal(	eStage_Game,
					eMBEVENT_NONE, 
					GAMERESOURCEMAN->GetGameText( 197 ),	// 소지금 부족
					GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
					eSKIN_OK
					);
			}
			break;
		case ItemBuyTarot:
			if( HERO->GetPVPPoint() < price )
			{
				UIMAN->CreateModal(	eStage_Game,
					eMBEVENT_NONE, 
					GAMERESOURCEMAN->GetGameText( 198 ),	// 소지금 부족
					GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
					eSKIN_OK
					);
			}
			break;
		default:
			{
				/// 코인류 - 코인일때는 GetBuyType() 이 아이템 인덱스임.
				unsigned long haveCount = GetItemCount( define->GetBuyType() );
				if( haveCount < price )
				{
					UIMAN->CreateModal(	eStage_Game,
						eMBEVENT_NONE, 
						GAMERESOURCEMAN->GetGameText( 199 ),	// 소지금 부족
						GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
						eSKIN_OK
						);
					return false;
				}
			}
			break;
		}

		/// 무게 검사
		float wei = mCurWeight + (define->GetWeight() * count);
		if( define->GetBuyType() <= ItemBuyTarot )
		{
			if( wei > mMaxWeight )
			{
				/// 무게게이지 풀
				UIMAN->CreateModal(	eStage_Game,
					eMBEVENT_NONE, 
					GAMERESOURCEMAN->GetGameText( 201 ),	// 무게게이지 풀
					GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
					eSKIN_OK
					);
				return false;
			}
		}
		else
		{
			/// 코인 소비후, 무게 측정 검사
			cItemDefine* coinDefine = GetItemDefine( define->GetBuyType() );
			if( coinDefine )
			{
				wei -= (float)(coinDefine->GetWeight() * define->GetBuyPrice());
				if( wei > mMaxWeight )
				{
					/// 무게게이지 풀
					UIMAN->CreateModal(	eStage_Game,
						eMBEVENT_NONE, 
						GAMERESOURCEMAN->GetGameText( 201 ),	// 무게게이지 풀
						GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
						eSKIN_OK
						);
					return false;
				}
			}
			else
			{
				assert(0);
				return false;
			}
		}
	}

	return true;
}


bool cItemManager::CheckDisjoint( unsigned int slotIndex )
{
	/// 검사
	if( HERO->GetState() == eOBJECT_STATE_DIE )
	{
		UIMAN->CreateModal(	eStage_Game,
			eMBEVENT_NONE, 
			GAMERESOURCEMAN->GetGameText( 235 ),
			GAMERESOURCEMAN->GetGameText( 301 ),
			eSKIN_OK
			);
		return false;
	}

	if( slotIndex > MAX_INVENTORY )
		return false;

	cItem& item = ITEMMAN->GetItem( slotIndex );
	cItemDefine* itemDefine = item.GetDefine();
    if( !itemDefine )
		return false;

	/// 분해 결과 아이템 정보
	sItemDisjoint* data = itemDefine->GetDisjoint();
	if( !data )
		return false;

	unsigned int weight = 0;
	for( int i = 0 ; i < MAX_DISJOINT; ++i )
	{
		if( data->mDisjoint[i].itemIndex == 0 )
			break;

		/// 무게 검사
		cItemDefine* define = ITEMMAN->GetItemDefine( data->mDisjoint[i].itemIndex );
		if( define )
			weight += (define->GetWeight() * data->mDisjoint[i].count);
	}

	/// 비용 검사
	if( HERO->GetMoney() < data->mPrice )
	{
		UIMAN->CreateModal(	eStage_Game,
			eMBEVENT_NONE, 
			GAMERESOURCEMAN->GetGameText( 200 ),	// 소지금 부족
			GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
			eSKIN_OK
			);
		return false;
	}

	/// 무게 검사
	if( weight > mMaxWeight )
	{
		/// 무게게이지 풀
		UIMAN->CreateModal(	eStage_Game,
			eMBEVENT_NONE, 
			GAMERESOURCEMAN->GetGameText( 201 ),	// 무게게이지 풀
			GAMERESOURCEMAN->GetGameText( 301 ),	// 알림
			eSKIN_OK
			);
		return false;
	}
	return true;
}

/// 아이템 변화시 모든 정보 갱신
void cItemManager::UpdateItem()
{
	/// 무게갱신
	CheckWeight();

	/// 총 갯수 갱신
	CheckItemCount();
	
	/// 퀵슬롯에 사용 여부 갱신
	QUICKMAN->CheckSkillIcon();
}

/// 인벤토리 내부 모든 아이템 무게 검사
void cItemManager::CheckWeight()
{
	/// 장비창 모든 아이템 무게 검사
	unsigned int totalWei = 0;
	for( unsigned int i = INVENTORY_EQUIP_BEGIN; i <= INVENTORY_HAND_END; ++i )
	{
		cItem& item = mItemArray[i];
		if( item.mDefine )
		{
			totalWei += item.mDefine->GetWeight() * item.mCount;
		}
	}

	/// 가방창 모든 아이템 무게 검사 ( 몰, 퀘스트 포함 )
	for( unsigned int i = INVENTORY_BAG_BEGIN; i <= INVENTORY_QUEST_END; ++i )
	{
		cItem& item = mItemArray[i];
		if( item.mDefine )
		{
			totalWei += item.mDefine->GetWeight() * item.mCount;
		}
	}

	mCurWeight = (float)totalWei;

	/// ui 갱신
	SetCurWeightGauge();
}

void cItemManager::SetMaxWeightGauge( float max )
{
	if( mWeightGauge )
	{
		mMaxWeight = max;
		mWeightGauge->SetMaxValue( max );

		SetCurWeightGauge();
	}
	else
	{
		assert(0);
	}
}

void cItemManager::SetCurWeightGauge()
{
	if( mWeightGauge )
	{
		mWeightGauge->SetGaugeNoAni( mCurWeight );

		cHeroInfoWindow* heroInfo = GAMEUI->GetHeroInfoWindow();
		if( heroInfo )
		{
			heroInfo->SetWeight( mCurWeight );
		}
	}
	else
	{
		assert(0);
	}
}

/// 아이템 총갯수 검사
void cItemManager::CheckItemCount()
{
	mItemCountMap.Clear();

	/// 가방창 모든 아이템 갯수 검사
	for( unsigned int i = INVENTORY_BAG_BEGIN; i <= INVENTORY_QUEST_END; ++i )
	{
		cItem& item = mItemArray[i];
		if( item.mDefine )
		{
			/// 겹치는 아이템만 갯수세기
			unsigned char type = item.mDefine->GetType();	
			unsigned char subtype = item.mDefine->GetSubType();

			///// 해당 종류가 아니면 넘기기
			//if( !(type == ITEM_ETC1) && !(type == ITEM_MATERIAL) && !(type == ITEM_COIN) && !(type == ITEM_CARD && subtype == ITEM_CARD_COMMON) )
			//	continue;

			/// 이미 갯수를 세어놓았으면 더하기
			cItemCountMap::cIterator i = mItemCountMap.Find( item.mIndex );
			if( i != mItemCountMap.End() )
			{
				/// 있으면 더하기
				unsigned int& total = (unsigned int)i->mSecond;
				total += item.mCount;
			}
			else
			{
				/// 없으면 새로삽입
				if( mItemCountMap.Insert( item.mIndex, item.mCount ) == false )
				{
					assert(0 && "error to insert item total count");
				}
			}
		}
	}

	/// 퀵슬롯의 아이템 총갯수 갱신
	QUICKMAN->CheckItemIcon();

	/// 아이템 조합중일경우만 갱신
	cItemMixWindow* win = GAMEUI->GetItemMixWindow();
	if( win && win->IsVisible() )
		win->CheckItemCount();
}

bool cItemManager::CreateDropItem( MSG_ITEM_INFO* dropMsg )
{
	if( dropMsg == 0 )
		return false;

	cDropItemSceneNodeParam param;
	param.mDropIndex = dropMsg->itemDrop.idx;
	param.mDropEndPos = NiPoint2( dropMsg->itemDrop.xPos, dropMsg->itemDrop.yPos );
	param.mTimeToOwn = dropMsg->timeToOwn;
	::memcpy( param.mOwner, dropMsg->owner, sizeof(unsigned long)*MAX_OWNER );

	cSceneNode* node = SCENEMAN->CreateDropItem( param );
	if( node == 0 )
		return false;

	if( mDropItemMap.Insert( dropMsg->itemDrop.idx, node->GetIndexByManger() ) == false )
	{
		assert( 0 && "failed to insert dropitem define, maybe already exist" );
		return false;
	}

	return true;
}

void cItemManager::DeleteDropItem( unsigned long idx )
{
	unsigned long nodeIdx = (unsigned long)mDropItemMap.GetAt( idx );
	cDropItemSceneNode* node = SCENEMAN->GetDropItemSceneNode( nodeIdx );
	if( node )
		SCENEMAN->DestroyDropItemNode( node );

	mDropItemMap.Erase( idx );
}

//bool cItemManager::ProcessMouseOver( int mouseX, int mouseY )
//{
//	tArray<void*> CollidableArray;
//	CollidableArray.Clear();
//
//	if( SCENEMAN->PickDropItem(&CollidableArray, mouseX, mouseY, true) == true )
//	{
//		cDropItemSceneNode* n = (cDropItemSceneNode*)CollidableArray[0];
//		if( n == 0 )
//			return false;
//
//		return true;
//	}
//	return false;
//}


//bool cItemManager::ProcessLButtonClick( int mouseX, int mouseY )
//{
//	tArray<void*> CollidableArray;
//	CollidableArray.Clear();
//
//	if( SCENEMAN->PickDropItem(&CollidableArray, mouseX, mouseY, true) == true )
//	{
//		cDropItemSceneNode* n = (cDropItemSceneNode*)CollidableArray[0];
//		if( n == 0 )
//			return false;
//
//		if( n->IsHeroOwner() )
//		{
//			unsigned long idx = n->GetDropIndex();
//			HERO->AfterItemPick( idx, n->GetWorldTranslate().x, n->GetWorldTranslate().y );
//		}
//		else
//		{
//			CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 211 ) );
//		}
//
//		return true;
//	}
//	return false;
//}
//
//bool cItemManager::ProcessLButtonDClick( int mouseX, int mouseY )
//{
////	if( HERO->GetState() == ePLAYER_STATE_ITEMPICK )
////		return false;
//
//	tArray<void*> CollidableArray;
//	CollidableArray.Clear();
//
//	if( SCENEMAN->PickDropItem(&CollidableArray, mouseX, mouseY, true) == true )
//	{
//		cDropItemSceneNode* n = (cDropItemSceneNode*)CollidableArray[0];
//		if( n == 0 )
//			return false;
//
//		unsigned long idx = n->GetDropIndex();
//		HERO->AfterItemPick( idx, n->GetWorldTranslate().x, n->GetWorldTranslate().y );
//		return true;
//	}
//
//	return false;
//}

void cItemManager::GetTooltipColor( unsigned short tiptype, unsigned long& color )
{
	color = eCOLOR_WHITE;
	switch( tiptype )
	{
	case eTOOLTIP_MALL:		color = eCOLOR_MALL;		break;
	case eTOOLTIP_ETC:		color = eCOLOR_ETC;			break;
	case eTOOLTIP_NORMAL:	color = eCOLOR_WHITE;		break;
	case eTOOLTIP_MAGIC:	color = eCOLOR_MAGIC;		break;
	case eTOOLTIP_RARE:		color = eCOLOR_RARE;		break;
	case eTOOLTIP_UNIQUE:	color = eCOLOR_UNIQUE;		break;
	case eTOOLTIP_EPIC:		color = eCOLOR_EPIC;		break;
	case eTOOLTIP_REGEND:	color = eCOLOR_REGEND;		break;
	}
}

unsigned long cItemManager::GetPriceUinit( unsigned long type )
{
	unsigned long index = 0;
	switch( type )
	{
	case ItemSellNone:	break;						// ItemBuyNone  와 동일
	case ItemSellMoney: index = 2000091; break;		// ItemBuyMoney 와 동일
	case ItemSellPvp:	index = 2000095; break;		// ItemBuyPvp	와 동일
	case ItemSellTarot:	index = 2000096; break;		// ItemBuyTarot	와 동일
	default:
		{
			/// 코인류
			cItemDefine* coinDefine = ITEMMAN->GetItemDefine( type );
			if( coinDefine )
			{
				switch( coinDefine->GetSubType() )
				{
				case ITEM_COIN_GOLD:	index = 2000092; break;
				case ITEM_COIN_SILVER:	index = 2000093; break;
				case ITEM_COIN_COPPER:	index = 2000094; break;
				}
			}
			else
			{
				assert(0);
			}
		}
		break;
	}

	return index;
}

/// 아이템명 줄여서 리턴
bool cItemManager::ModifyItemName( LPCTSTR name, TCHAR* out )
{
	/// 이름 길이 조절
	int len = ::_tcslen( name );
	if( len > MAX_ITEMNAME_LEN )
	{
		int cutlen = 0; 
		unsigned int cutWidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_System, name, len );

		while( (int)cutWidth > MAX_NAME_WIDTH ) 
		{
			/// 계속 검사할필요 없음.
			if( cutlen > len )
				break;

			cutlen++;
			cutWidth = FONTAGENT->GetTextExtent( cFontAgent::eFont_System, name, len - cutlen );
		}

		if( cutlen > 0 )
		{
			if( len - cutlen > 1 )
			{
				::_tcsncpy( out, &name[0], len - cutlen - 1 );
				::_tcsncat( out, _T("…"), 1 );
				return true;
			}
		}
	}
	return false;
}

bool cItemManager::CheckNearestDropItem()
{
	if( HERO->IsDie() == true )
		return false;

	if( mDropItemMap.IsEmpty() == true )
		return false;

	cDropItemMap::cIterator i = mDropItemMap.Begin();
	cDropItemMap::cIterator iend = mDropItemMap.End();

	NiPoint3 heroPos = HERO->GetPos();
	float dist = 0;
	cDropItemSceneNode* nearestDropItem = 0;
	float nearestDist = FLT_MAX;
	for( ; i != iend; ++i )
	{
		unsigned long nodeIdx = (unsigned long)(i->mSecond);
		cDropItemSceneNode* n = SCENEMAN->GetDropItemSceneNode( nodeIdx );
		if( n==0 || n->IsHeroOwner() == false )
			continue;

		dist = (heroPos - n->GetWorldTranslate()).Length();

		if( dist <= 1000.0f )
		{
			if( dist < nearestDist )
			{
				nearestDist = dist;
				nearestDropItem = n;
			}
		}
	}

	if( nearestDropItem )
	{
		unsigned long idx = nearestDropItem->GetDropIndex();
		HERO->AfterItemPick( idx, nearestDropItem->GetWorldTranslate().x, nearestDropItem->GetWorldTranslate().y );
		return true;
	}
	return false;
}

bool cItemManager::CheckOpenTime() 
{
	if( THEAPP->GetWorldAccumTime() - mLastAccutime > OPEN_TIME )
	{
		mLastAccutime = THEAPP->GetWorldAccumTime();
		return true;
	}
	return false;
}

//ItemActiveFront = left2, right2
//ItemActiveBack = left1, right1
void cItemManager::SetSwitchWeapon( eItemActiveWeapon activeWeapon )
{
	/// 
	if( !(activeWeapon == ItemActiveFront || activeWeapon == ItemActiveBack) )
	{
		assert(0);
		return;
	}

	cItem& rItem0 = mItemArray[INVENTORY_HAND_RIGHT1];
	cItem& rItem1 = mItemArray[INVENTORY_HAND_RIGHT2];
	cItem& lItem0 = mItemArray[INVENTORY_HAND_LEFT1];
	cItem& lItem1 = mItemArray[INVENTORY_HAND_LEFT2];

	/// 저장
	mActiveWeapon = activeWeapon;

	/// 위치 변경
	if( mActiveWeapon == ItemActiveFront )
	{
		rItem1.SwicthPosition( mFrontRight );
		lItem1.SwicthPosition( mFrontLeft );

		rItem0.SwicthPosition( mBackRight );
		lItem0.SwicthPosition( mBackLeft );
	}
	else if( mActiveWeapon == ItemActiveBack )
	{
		rItem0.SwicthPosition( mFrontRight );
		lItem0.SwicthPosition( mFrontLeft );

		rItem1.SwicthPosition( mBackRight );
		lItem1.SwicthPosition( mBackLeft );
	}
	else
	{
		assert(0);
	}

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

	CheckItemSlot( INVENTORY_HAND_RIGHT1 );
	CheckItemSlot( INVENTORY_HAND_RIGHT2 );

	ChangeSelectSlot( INVENTORY_HAND_RIGHT1 );
	ChangeSelectSlot( INVENTORY_HAND_RIGHT2 );
}

void cItemManager::SetWeaponIconPos( unsigned int slotIndex, cUIRect rect )
{
	if( slotIndex == INVENTORY_HAND_LEFT1 )
	{
		mBackLeft = rect;
	}
	else if( slotIndex == INVENTORY_HAND_RIGHT1 )
	{
		mBackRight = rect;
	}
	else if( slotIndex == INVENTORY_HAND_LEFT2 )
	{
		mFrontLeft = rect;
	}
	else if( slotIndex == INVENTORY_HAND_RIGHT2 )
	{
		mFrontRight = rect;
	}
}
