#include "RoleDataEx.h"
#include <algorithm>
#include "basefunction/BaseFunction.h"
//------------------------------------------------------------------------------------------------------------------------------------
// 0 Body 1 Bank 2 EQ
ItemFieldStruct* RoleDataEx::GetItem  ( int Pos , int Type )   
{
    switch( Type )
    {
    case 0:
        return GetBodyItem( Pos );
    case 1:
        return GetBankItem( Pos );
    case 2:
        return GetEqItem( Pos );
    }

    return NULL;
}

int  RoleDataEx::GetBodyItemPos( int OrgID , int Version )
{    
    for( int i = 0 ; i < _MAX_BODY_COUNT_ ; i++ )
    {
        ItemFieldStruct* Temp = &BaseData.Body.Item[ i ];
        if(     Temp->OrgObjID == OrgID 
            && ( Version == 0 || Temp->Serial == Version ) )
            return i;
    }
    return -1;
}
int RoleDataEx::GetBankItemPos( int OrgID , int Version )
{
    for( int i = 0 ; i < _MAX_BODY_COUNT_ ; i++ )
    {
        ItemFieldStruct* Temp = &BaseData.Bank.Item[ i ];
        if(     Temp->OrgObjID == OrgID 
            && ( Version == 0 || Temp->Serial == Version ) )
            return i;
    }
    return -1;

}
int RoleDataEx::GetEqItemPos  ( int OrgID , int Version )
{
    for( int i = 0 ; i < EM_EQWearPos_MaxCount ; i++ )
    {
        ItemFieldStruct* Temp = &BaseData.EQ.Item[ i ];
        if(     Temp->OrgObjID == OrgID 
            && ( Version == 0 || Temp->Serial == Version ) )
            return i;
    }
    return -1;
}

ItemFieldStruct* RoleDataEx::GetBodyItem( int Pos )
{    
    if( (unsigned)Pos > _MAX_BODY_COUNT_ )
        return NULL;
    return &BaseData.Body.Item[ Pos ];
}
ItemFieldStruct* RoleDataEx::GetBankItem( int Pos )
{
    if( (unsigned)Pos > _MAX_BODY_COUNT_ )
        return NULL;

    return &BaseData.Bank.Item[ Pos ];
}
ItemFieldStruct* RoleDataEx::GetEqItem  ( int Pos )
{
    if( (unsigned)Pos > EM_EQWearPos_MaxCount )
        return NULL;

    return &BaseData.EQ.Item[ Pos ];
}

int RoleDataEx::BodyMoney(  )
{
    return BaseData.Body.Money;
}
int RoleDataEx::BankMoeny( )
{
    return BaseData.Bank.Money;
}

void RoleDataEx::BodyMoney( int Value )
{
    TempData.UpdateInfo.Money = true;
    BaseData.Body.Money = Value;
}
void RoleDataEx::BankMoeny( int Value )
{
    TempData.UpdateInfo.Money = true;
    BaseData.Bank.Money = Value;
}

SellItemFieldStruct* RoleDataEx::GetSellItem( int Pos )
{
	if ( (unsigned)Pos > _MAX_SELL_ITEM_SAVE_COUNT_ )
		return NULL;

	return &TempData.SellItemBackup[Pos];
}

int RoleDataEx::GetSellItemCount()
{
	return TempData.SellItemBackup.Size();
}

//檢查欄位資料是否有問題
bool    RoleDataEx::CheckBodyItem( ItemFieldStruct& Item , int Pos )
{
    if( ( unsigned )Pos >= _MAX_BODY_COUNT_ || Pos >= BaseData.Body.Count  )
        return false;

    if(		Item == *GetBodyItem( Pos ) )
        return true;

    return false; 
}

bool    RoleDataEx::CheckBankItem( ItemFieldStruct& Item , int Pos )
{
    if( ( unsigned )Pos >= _MAX_BODY_COUNT_ || Pos >= BaseData.Bank.Count  )
        return false;

    if(		Item == *GetBankItem( Pos ) )
        return true;

    return false; 
}
//------------------------------------------------------------------------------------------------------------------------------------
bool    RoleDataEx::CheckEQItem( ItemFieldStruct& Item , int Pos )
{
    if( ( unsigned )Pos >= EM_EQWearPos_MaxCount   )
        return false;

    if(		Item == *GetEqItem( Pos ) )
        return true;

    return false; 
}

//------------------------------------------------------------------------------------------------------------------------------------
//把暫存區的物品取到身上
//Item 為確定的物品資料
RoleDataResultENUM RoleDataEx::GetItemBuftoBody( ItemFieldStruct& Item , int Pos , int Count )
{
	if( Count < 0 )
		return EM_RoleData_CountErr;

    if( TempData.ItemTemp.Size() <= 0 )
        return EM_RoleData_BufferEmpty;

    if( Count > Item.Count )
        return EM_RoleData_CountErr;


    //檢查是否超過可放置欄位
    if( ( unsigned int ) Pos >= ( unsigned int )BaseData.Body.Count )
		return EM_RoleData_PosErr;

	GameObjDbStructEx*	OrgDB;
	OrgDB = St_GetObjDB( Item.OrgObjID );
	if( OrgDB == NULL )
		return EM_RoleData_DataInfoErr;

	if( OrgDB->MaxHeap < Count + GetBodyItem( Pos )->Count )
		return  EM_RoleData_PosErr;
//        ||  !IsBodyEmpty( Pos ) )
//        return EM_RoleData_PosErr;

    //檢查要放製的位置是否可以放
    if(	TempData.ItemTemp.Front() != Item )
        return EM_RoleData_DataInfoErr;

    if( TempData.ItemTemp.Front().Count == Count )
        TempData.ItemTemp.Erase( 0 );
    else
        TempData.ItemTemp.Front().Count -= Count;

	if( IsBodyEmpty( Pos ) )
		*GetBodyItem(Pos) = Item;
	else
	{
		GetBodyItem(Pos)->Count += Count;
		Item = *(GetBodyItem(Pos));
	}


    TempData.UpdateInfo.Body = true;
    return EM_RoleData_OK;

}
//------------------------------------------------------------------------------------------------------------------------------------
//加一個物品到身上某位置
RoleDataResultENUM RoleDataEx::AddItemtoBody( ItemFieldStruct& Item , int Pos )
{
    //檢查是否超過可放置欄位
    if(     ( unsigned int )Pos >= ( unsigned int )BaseData.Body.Count 
        ||  !IsBodyEmpty( Pos ) )
        return EM_RoleData_PosErr;

    *GetBodyItem(Pos) = Item;

    TempData.UpdateInfo.Body = true;
    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
//刪除一個物品到身上某位置
RoleDataResultENUM RoleDataEx::DelItemFromBody( ItemFieldStruct& Item , int Pos )
{
    //檢查是否超過可放置欄位
    if( ( unsigned int )Pos >= ( unsigned int )BaseData.Body.Count )
        return EM_RoleData_PosErr;

    //檢查要放製的位置是否可以放
    if(	*GetBodyItem(Pos) != Item )
        return EM_RoleData_DataInfoErr;

    GetBodyItem(Pos)->Init();


    TempData.UpdateInfo.Body = true;
    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
//加一個物品到銀行某位置
RoleDataResultENUM RoleDataEx::AddItemtoBank( ItemFieldStruct& Item , int Pos )
{
    //檢查是否超過可放置欄位
    if(     ( unsigned int )Pos >= ( unsigned int )BaseData.Bank.Count 
        ||  !IsBankEmpty( Pos ) )
        return EM_RoleData_PosErr;

    *GetBankItem(Pos) = Item;

    TempData.UpdateInfo.Bank = true;
    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
//刪除一個物品到銀行某位置
RoleDataResultENUM RoleDataEx::DelItemFromBank( ItemFieldStruct& Item , int Pos )
{
    //檢查是否超過可放置欄位
    if( (unsigned int) Pos >= ( unsigned int )BaseData.Bank.Count )
        return EM_RoleData_PosErr;

    //檢查要放製的位置是否可以放
    if(	*GetBankItem( Pos ) != Item )
        return EM_RoleData_DataInfoErr;

    GetBankItem(Pos)->Init();

    TempData.UpdateInfo.Bank = true;
    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
//刪除一個裝備
RoleDataResultENUM RoleDataEx::DelItemFromEQ( ItemFieldStruct& Item , int Pos )
{
    //檢查是否超過可放置欄位
    if( (unsigned int) Pos >= EM_EQWearPos_MaxCount )
        return EM_RoleData_PosErr;

    //檢查要放製的位置是否可以放
    if(	BaseData.EQ.Item[Pos] != Item )
        return EM_RoleData_DataInfoErr;

    BaseData.EQ.Item[Pos].Init();

    TempData.UpdateInfo.Eq = true;
    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
//身體物品交換
RoleDataResultENUM RoleDataEx::ExchangeBodyItem(	ItemFieldStruct& Item1 , int Pos1  
                                                ,	ItemFieldStruct& Item0 , int Pos0  )
{

    if( Pos0 == Pos1 )
        return EM_RoleData_PosErr;

    if( (unsigned int)Pos0 >= _MAX_BODY_COUNT_ || (unsigned int)Pos1 >= _MAX_BODY_COUNT_ )
        return EM_RoleData_PosErr;

    if(		CheckBodyItem( Item0 , Pos0 ) == false
        ||	CheckBodyItem( Item1 , Pos1 ) == false )
        return EM_RoleData_DataInfoErr;
    
    
    if( Item0.OrgObjID != Item1.OrgObjID )
    {
        std::swap( *GetBodyItem( Pos0 ) , *GetBodyItem( Pos1) );
        return EM_RoleData_OK;
    }
    
    GameObjDbStructEx*	OrgDB;
    OrgDB = St_GetObjDB( Item0.OrgObjID );

    if( OrgDB == NULL )
    {
        GetBodyItem( Pos0 )->Init();
        GetBodyItem( Pos1 )->Init();
        return EM_RoleData_OrgObjIDErr;
    }

    if( OrgDB->MaxHeap == 1 )
    {
        std::swap( *GetBodyItem( Pos0 ) , *GetBodyItem( Pos1) );
        return EM_RoleData_OK;
    }
    
    if( OrgDB->MaxHeap >= GetBodyItem( Pos0 )->Count + GetBodyItem( Pos1 )->Count )
    {
        GetBodyItem( Pos0 )->Count += GetBodyItem( Pos1 )->Count;
        GetBodyItem( Pos1 )->Init();
    }
    else
    {
        GetBodyItem( Pos1 )->Count = GetBodyItem( Pos1 )->Count + GetBodyItem( Pos0 )->Count - OrgDB->MaxHeap;
        GetBodyItem( Pos0 )->Count = OrgDB->MaxHeap;
    }

    TempData.UpdateInfo.Body= true;

    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
//銀行物品交換
RoleDataResultENUM RoleDataEx::ExchangeBankItem(	ItemFieldStruct& Item0 , int Pos0  
                                                ,	ItemFieldStruct& Item1 , int Pos1  )
{
    if( Pos0 == Pos1 )
        return EM_RoleData_PosErr;

    if( (unsigned int)Pos0 >= _MAX_BODY_COUNT_ || (unsigned int)Pos1 >= _MAX_BODY_COUNT_ )
        return EM_RoleData_PosErr;

    if(		CheckBankItem( Item0 , Pos0 ) == false
        ||	CheckBankItem( Item1 , Pos1 ) == false )
        return EM_RoleData_DataInfoErr;


    if( Item0.OrgObjID != Item1.OrgObjID )
    {
        std::swap( *GetBankItem( Pos0 ) , *GetBankItem( Pos1) );
        return EM_RoleData_OK;
    }

    GameObjDbStructEx*	OrgDB;
    OrgDB = St_GetObjDB( Item0.OrgObjID );

    if( OrgDB == NULL )
    {
        GetBankItem( Pos0 )->Init();
        GetBankItem( Pos1 )->Init();
        return EM_RoleData_OrgObjIDErr;
    }

    if( OrgDB->MaxHeap == 1 )
    {
        std::swap( *GetBankItem( Pos0 ) , *GetBankItem( Pos1) );
        return EM_RoleData_OK;
    }

    if( OrgDB->MaxHeap >= GetBankItem( Pos0 )->Count + GetBankItem( Pos1 )->Count )
    {
        GetBankItem( Pos0 )->Count += GetBankItem( Pos1 )->Count;
        GetBankItem( Pos1 )->Init();
    }
    else
    {
        GetBankItem( Pos1 )->Count = GetBankItem( Pos1 )->Count + GetBankItem( Pos0 )->Count - OrgDB->MaxHeap;
        GetBankItem( Pos0 )->Count = OrgDB->MaxHeap;
    }

    TempData.UpdateInfo.Bank = true;

    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
//身體與銀行交換物品
RoleDataResultENUM RoleDataEx::ExchangeBodyBankItem(	ItemFieldStruct& BodyItem , int BodyPos  
                                                    ,	ItemFieldStruct& BankItem , int BankPos  )
{
    if( (unsigned int)BodyPos >= _MAX_BODY_COUNT_ || (unsigned int)BankPos >= _MAX_BODY_COUNT_ )
        return EM_RoleData_PosErr;

    if(		CheckBodyItem( BodyItem , BodyPos ) == false
        ||	CheckBankItem( BankItem , BankPos ) == false )
        return EM_RoleData_DataInfoErr;


    if( BodyItem.OrgObjID != BankItem.OrgObjID )
    {
        //std::swap( BodyItem( BodyPos ) , BankItem( BankPos) );
        std::swap( BaseData.Body.Item[ BodyPos ] , BaseData.Bank.Item[ BankPos ] );
        return EM_RoleData_OK;
    }

    GameObjDbStructEx*	OrgDB;
    OrgDB = St_GetObjDB( BodyItem.OrgObjID );

    if( OrgDB == NULL )
    {
        GetBodyItem( BodyPos )->Init();
        GetBankItem( BankPos )->Init();
        return EM_RoleData_OrgObjIDErr;
    }

    if( OrgDB->MaxHeap == 1 )
    {
        std::swap( *GetBodyItem( BodyPos ) , *GetBankItem( BankPos ) );
        return EM_RoleData_OK;
    }

    if( OrgDB->MaxHeap >= GetBodyItem( BodyPos )->Count + GetBankItem( BankPos )->Count )
    {
        GetBodyItem( BodyPos )->Count += GetBankItem( BankPos )->Count;
        GetBankItem( BankPos )->Init();
    }
    else
    {
        GetBankItem( BankPos )->Count = GetBankItem( BankPos )->Count + GetBodyItem( BodyPos )->Count - OrgDB->MaxHeap;
        GetBodyItem( BodyPos )->Count = OrgDB->MaxHeap;
    }

    TempData.UpdateInfo.Bank = true;
    TempData.UpdateInfo.Body = true;
    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
bool    RoleDataEx::CheckBaseSetEQ( int EQPos , GameObjDbStructEx*	BodyOrgDB )
{
    if( BodyOrgDB == NULL )
        return true;

    
    if( BodyOrgDB->IsWeapon() )
    {
        switch( BodyOrgDB->Item.WeaponPos )
        {
        case EM_WeaponPos_MainHand:     
            {
                if( EQPos != EM_EQWearPos_MainHand )
                    return false;
            }
            break;
        case EM_WeaponPos_SecondHand:
            {
                if( EQPos != EM_EQWearPos_SecondHand )
                {
                    return false;
                }
            }
            break;
        case EM_WeaponPos_OneHand:      
            {
                if(     EQPos != EM_EQWearPos_MainHand
                    &&  EQPos != EM_EQWearPos_SecondHand)
                    return false;

            }
            break;
        case EM_WeaponPos_TwoHand:      
            {
                if( EQPos != EM_EQWearPos_MainHand )
                    return false;

            }
            break;
        case EM_WeaponPos_Ammo:         
            {
                if( EQPos != EM_EQWearPos_Ammo )
                    return false;
            }
            break;
		case EM_WeaponPos_Manufacture:         
			{
				if( EQPos != EM_WeaponPos_Manufacture )
					return false;
			}
			break;
        }
    }
    else if( BodyOrgDB->IsArmor() )
    {
        switch( BodyOrgDB->Item.ArmorPos )
        {
        case EM_ArmorPos_Head:     
        case EM_ArmorPos_Gloves:	   
        case EM_ArmorPos_Shoes:	   
        case EM_ArmorPos_Clothes:
        case EM_ArmorPos_Pants:	   
        case EM_ArmorPos_Back:	   
        case EM_ArmorPos_Belt:	   
        case EM_ArmorPos_Shoulder:  
        case EM_ArmorPos_Necklace:  
            {
                if( EQPos != BodyOrgDB->Item.ArmorPos )
                    return false;
            }
            break;

        case EM_ArmorPos_Ring:  
            {
                if(     EQPos != EM_EQWearPos_Ring1 
                    &&  EQPos != EM_EQWearPos_Ring2 )
                    return false;
            }
            break;
        case EM_ArmorPos_Earring:
            {
                if(     EQPos != EM_EQWearPos_Earring1 
                    &&  EQPos != EM_EQWearPos_Earring2 )
                    return false;
            }
            break;
        case EM_ArmorPos_SecondHand:
            {
                if( EQPos != EM_EQWearPos_SecondHand )
                {
                    return false;
                }
            }
            break;
        }
    }
    else 
    {
        return false;
    }
    
    if( CheckLimit( BodyOrgDB->Limit ) == false )
        return false;

    return true;
}
//------------------------------------------------------------------------------------------------------------------------------------
//檢查裝備限制
bool	RoleDataEx::CheckEQLimit( GameObjDbStructEx*	BodyOrgDB )
{
	if( BodyOrgDB->CheckItemAndEqSkill( TempData.Attr.Fin.WearSkill) == false )
		return false;

	if( CheckLimit( BodyOrgDB->Limit ) == false )
		return false;

	return true;
}

//檢查是否可以置換此項裝備
bool    RoleDataEx::CheckSetEQ( int EQPos , GameObjDbStructEx*	BodyOrgDB )
{

    if( BodyOrgDB == NULL )
		return true;

	if( BodyOrgDB->CheckItemAndEqSkill( TempData.Attr.Fin.WearSkill) == false )
		return false;

    if( BodyOrgDB->IsWeapon() )
    {
        switch( BodyOrgDB->Item.WeaponPos )
        {
        case EM_WeaponPos_MainHand:     
            {
                if( EQPos != EM_EQWearPos_MainHand )
                    return false;
            }
            break;
        case EM_WeaponPos_SecondHand:
            {
                if( EQPos != EM_EQWearPos_SecondHand )
                {
                    return false;
                }
                //檢查主手是否是有裝備
                GameObjDbStructEx*	MainHandDB = St_GetObjDB(  GetEqItem( EM_EQWearPos_MainHand )->OrgObjID );
                if( MainHandDB != NULL && MainHandDB->Item.WeaponPos == EM_WeaponPos_TwoHand )
                {
                    return  false;
                }
            }
            break;
        case EM_WeaponPos_OneHand:      
            {
                if(     EQPos != EM_EQWearPos_MainHand
                    &&  EQPos != EM_EQWearPos_SecondHand)
                    return false;

                if( EQPos == EM_EQWearPos_SecondHand )
                {
                    //檢查主手是否是有裝備
                    GameObjDbStructEx*	MainHandDB = St_GetObjDB(  GetEqItem( EM_EQWearPos_MainHand )->OrgObjID );
                    if( MainHandDB != NULL && MainHandDB->Item.WeaponPos == EM_WeaponPos_TwoHand )
                    {
                        return  false;
                    }
                }
            }
            break;
        case EM_WeaponPos_TwoHand:      
            {
                if( EQPos != EM_EQWearPos_MainHand )
                    return false;
                //檢查副手是否是有裝備
                if( GetEqItem( EM_EQWearPos_SecondHand )->IsEmpty() == false )
                {
                    return  false;
                }
            }
            break;
        case EM_WeaponPos_Ammo:         
            {
                if( EQPos != EM_EQWearPos_Ammo )
                    return false;
            }
            break;
		case EM_WeaponPos_Manufacture:         
			{
				if( EQPos != EM_WeaponPos_Manufacture )
					return false;
			}
			break;
        }
    }
    else if( BodyOrgDB->IsArmor() )
    {
        switch( BodyOrgDB->Item.ArmorPos )
        {
        case EM_ArmorPos_Head:     
        case EM_ArmorPos_Gloves:	   
        case EM_ArmorPos_Shoes:	   
        case EM_ArmorPos_Clothes:
        case EM_ArmorPos_Pants:	   
        case EM_ArmorPos_Back:	   
        case EM_ArmorPos_Belt:	   
        case EM_ArmorPos_Shoulder:  
        case EM_ArmorPos_Necklace:  
            {
                if( EQPos != BodyOrgDB->Item.ArmorPos )
                    return false;
            }
            break;

        case EM_ArmorPos_Ring:  
            {
                if(     EQPos != EM_EQWearPos_Ring1 
                    &&  EQPos != EM_EQWearPos_Ring2 )
                    return false;
            }
            break;
        case EM_ArmorPos_Earring:
            {
                if(     EQPos != EM_EQWearPos_Earring1 
                    &&  EQPos != EM_EQWearPos_Earring2 )
                    return false;
            }
            break;
        case EM_ArmorPos_SecondHand:
            {
                if( EQPos != EM_EQWearPos_SecondHand )
                {
                    return false;
                }
                //檢查主手是否是有裝備
                GameObjDbStructEx*	MainHandDB = St_GetObjDB(  GetEqItem( EM_EQWearPos_MainHand )->OrgObjID );
                if( MainHandDB != NULL && MainHandDB->Item.WeaponPos == EM_WeaponPos_TwoHand )
                {
                    return  false;
                }
            }
            break;
        }
    }
    else
    {
        return false;
    }

    if( CheckLimit( BodyOrgDB->Limit ) == false )
        return false;

    return true;
}
//------------------------------------------------------------------------------------------------------------------------------------
//身體與銀行交換物品
RoleDataResultENUM RoleDataEx::ExchangeBodyEQItem(	ItemFieldStruct& BodyItem , int BodyPos  
                                                  ,	ItemFieldStruct& EQItem   , int EQPos   )
{
    if( (unsigned int)BodyPos >= _MAX_BODY_COUNT_ || (unsigned int)EQPos >= EM_EQWearPos_MaxCount )
        return EM_RoleData_PosErr;

    if(		CheckBodyItem( BodyItem , BodyPos ) == false
        ||	CheckEQItem( EQItem , EQPos ) == false )
        return EM_RoleData_DataInfoErr;


    GameObjDbStructEx*	BodyOrgDB;
    BodyOrgDB   = St_GetObjDB( BodyItem.OrgObjID );
    if( CheckSetEQ( EQPos , BodyOrgDB ) == false )
        return EM_RoleData_EQWearPosErr;
    
    std::swap( BaseData.Body.Item[ BodyPos ] , BaseData.EQ.Item[ EQPos ] );
	TempData.UpdateInfo.Eq   = true;
	TempData.UpdateInfo.Body = true;
    return EM_RoleData_OK;
}

//銀行與裝備交換物品
RoleDataResultENUM RoleDataEx::ExchangeBankEQItem(	    ItemFieldStruct& BankItem   , int BankPos 
                                                    ,   ItemFieldStruct& EQItem     , int EQPos  )
{
    if( (unsigned int)BankPos >= _MAX_BODY_COUNT_ || (unsigned int)EQPos >= EM_EQWearPos_MaxCount )
        return EM_RoleData_PosErr;

    if(		CheckBankItem( BankItem , BankPos ) == false
        ||	CheckEQItem( EQItem , EQPos ) == false )
        return EM_RoleData_DataInfoErr;


    GameObjDbStructEx*	OrgDB;
    OrgDB   = St_GetObjDB( BankItem.OrgObjID );
    if( CheckSetEQ( EQPos , OrgDB ) == false )
        return EM_RoleData_EQWearPosErr;

    std::swap( BaseData.Bank.Item[ BankPos ] , BaseData.EQ.Item[ EQPos ] );
	TempData.UpdateInfo.Eq   = true;
	TempData.UpdateInfo.Bank = true;
    return EM_RoleData_OK;
}

bool    RoleDataEx::CheckEQSwap ( int Pos1, int Pos2 )
{
    GameObjDbStructEx*	OrgDB1;
    GameObjDbStructEx*	OrgDB2;

	if( (unsigned int)Pos1 >= EM_EQWearPos_MaxCount || (unsigned int)Pos1 >= EM_EQWearPos_MaxCount )
		return false;

    OrgDB1   = St_GetObjDB( GetEqItem( Pos1 )->OrgObjID );
    OrgDB2   = St_GetObjDB( GetEqItem( Pos2 )->OrgObjID );

    if( OrgDB1 != NULL )
    {
        if( OrgDB1->Item.Class == EM_Item_Weapon )
        {
            switch( OrgDB1->Item.WeaponPos )
            {
            case EM_WeaponPos_MainHand:     
            case EM_WeaponPos_SecondHand:
            case EM_WeaponPos_TwoHand:      
            case EM_WeaponPos_Ammo:         
			case EM_WeaponPos_Manufacture:

                return false;

            case EM_WeaponPos_OneHand:      
                {
                    if(     Pos2 != EM_EQWearPos_MainHand
                        &&  Pos2 != EM_EQWearPos_SecondHand)
                        return false;
                }
                break;
            }
        }
        else
        {
            switch( OrgDB1->Item.ArmorPos )
            {
            case EM_ArmorPos_Head:     
            case EM_ArmorPos_Gloves:	   
            case EM_ArmorPos_Shoes:	   
            case EM_ArmorPos_Clothes:
            case EM_ArmorPos_Pants:	   
            case EM_ArmorPos_Back:	   
            case EM_ArmorPos_Belt:	   
            case EM_ArmorPos_Shoulder:  
            case EM_ArmorPos_Necklace:  
            case EM_ArmorPos_SecondHand:
                {
                    return false;
                }
                break;

            case EM_ArmorPos_Ring:  
                {
                    if(     Pos2 != EM_EQWearPos_Ring1 
                        &&  Pos2 != EM_EQWearPos_Ring2 )
                        return false;
                }
                break;
            case EM_ArmorPos_Earring:
                {
                    if(     Pos2 != EM_EQWearPos_Earring1 
                        &&  Pos2 != EM_EQWearPos_Earring2 )
                        return false;
                }
                break;
            }
        }
    }

    if( OrgDB2!= NULL )
    {
        if( OrgDB2->Item.Class == EM_Item_Weapon )
        {
            switch( OrgDB2->Item.WeaponPos )
            {
            case EM_WeaponPos_MainHand:     
            case EM_WeaponPos_SecondHand:
            case EM_WeaponPos_TwoHand:      
            case EM_WeaponPos_Ammo:         
			case EM_WeaponPos_Manufacture:
                return false;

            case EM_WeaponPos_OneHand:      
                {
                    if(     Pos1 != EM_EQWearPos_MainHand
                        &&  Pos1 != EM_EQWearPos_SecondHand)
                        return false;
                }
                break;
            }
        }
        else
        {
            switch( OrgDB2->Item.ArmorPos )
            {
            case EM_ArmorPos_Head:     
            case EM_ArmorPos_Gloves:	   
            case EM_ArmorPos_Shoes:	   
            case EM_ArmorPos_Clothes:
            case EM_ArmorPos_Pants:	   
            case EM_ArmorPos_Back:	   
            case EM_ArmorPos_Belt:	   
            case EM_ArmorPos_Shoulder:  
            case EM_ArmorPos_Necklace:  
            case EM_ArmorPos_SecondHand:
                {
                    return false;
                }
                break;

            case EM_ArmorPos_Ring:  
                {
                    if(     Pos1 != EM_EQWearPos_Ring1 
                        &&  Pos1 != EM_EQWearPos_Ring2 )
                        return false;
                }
                break;
            case EM_ArmorPos_Earring:
                {
                    if(     Pos1 != EM_EQWearPos_Earring1 
                        &&  Pos1 != EM_EQWearPos_Earring2 )
                        return false;
                }
                break;
            }
        }
    }
    return true;
}

//裝備換物品
RoleDataResultENUM RoleDataEx::ExchangeEQItem(     ItemFieldStruct& Item1   , int Pos1  
                                               ,   ItemFieldStruct& Item2   , int Pos2  )
{
    if( Pos1 == Pos2 )
        return EM_RoleData_PosErr;

    if( (unsigned int)Pos1 >= EM_EQWearPos_MaxCount || Pos2 >= (unsigned int)EM_EQWearPos_MaxCount )
        return EM_RoleData_PosErr;

    if(		CheckEQItem( Item1 , Pos1 ) == false
        ||	CheckEQItem( Item2 , Pos2 ) == false )
        return EM_RoleData_DataInfoErr;

/*
    GameObjDbStruct*	OrgDB1;
    GameObjDbStruct*	OrgDB2;
    OrgDB1   = St_GetObjDB( Item1.OrgObjID );
    OrgDB2   = St_GetObjDB( Item2.OrgObjID );
*/
    if( CheckEQSwap( Pos1  , Pos2 ) == false )
        return EM_RoleData_EQWearPosErr;

    std::swap( BaseData.EQ.Item[ Pos1 ] , BaseData.EQ.Item[ Pos2 ] );
	TempData.UpdateInfo.Eq   = true;
    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
//身體與銀行交換物品
RoleDataResultENUM RoleDataEx::ExchangeBankBodyItem(	ItemFieldStruct& BankItem , int BankPos  
                                                    ,   ItemFieldStruct& BodyItem , int BodyPos  )
{

    if( (unsigned int)BankPos >= _MAX_BODY_COUNT_ || (unsigned int)BodyPos >= _MAX_BODY_COUNT_ )
        return EM_RoleData_PosErr;

    if(		CheckBodyItem( BodyItem , BodyPos ) == false
        ||	CheckBankItem( BankItem , BankPos ) == false )
        return EM_RoleData_DataInfoErr;


    if( BankItem.OrgObjID != BodyItem.OrgObjID )
    {
        std::swap( BaseData.Body.Item[ BodyPos ] , BaseData.Bank.Item[ BankPos ] );
        return EM_RoleData_OK;
    }

    GameObjDbStructEx*	OrgDB;
    OrgDB = St_GetObjDB( BodyItem.OrgObjID );

    if( OrgDB == NULL )
    {
        GetBodyItem( BodyPos )->Init();
        GetBankItem( BankPos )->Init();
        return EM_RoleData_OrgObjIDErr;
    }

    if( OrgDB->MaxHeap == 1 )
    {
         std::swap( BaseData.Body.Item[ BodyPos ] , BaseData.Bank.Item[ BankPos ] );
        return EM_RoleData_OK;
    }

    if( OrgDB->MaxHeap >= GetBodyItem( BodyPos )->Count + GetBankItem( BankPos )->Count )
    {
        GetBankItem( BankPos )->Count += GetBodyItem( BodyPos )->Count;
        GetBodyItem( BodyPos )->Init();
    }
    else
    {
        GetBodyItem( BodyPos )->Count = GetBodyItem( BodyPos )->Count + GetBankItem( BankPos )->Count - OrgDB->MaxHeap;
        GetBankItem( BankPos )->Count = OrgDB->MaxHeap;
    }

    TempData.UpdateInfo.Bank = true;
    TempData.UpdateInfo.Body = true;
    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------------------------------------------------------
//把身上某欄位物品分出一部份到另外一個欄位
RoleDataResultENUM RoleDataEx::ApartBodyItem(	ItemFieldStruct& Item , int PosSrc 
                                            ,	int CountDes , int PosDes  )
{

    if( CountDes <= 0 )
        return EM_RoleData_ApartSizeErr;

    if( CheckBodyItem( Item , PosSrc ) == false )
        return EM_RoleData_DataInfoErr;

    //ItemFieldStruct *TempItem  = &( BaseData.ItemBody[PosSrc] );

    if( GetBodyItem( PosSrc )->Count < CountDes )
        return EM_RoleData_ApartSizeErr;

    int ResultCount = GetBodyItem( PosSrc )->Count - CountDes;
    GetBodyItem( PosSrc )->Count = CountDes;

    AddItemtoBody( *GetBodyItem( PosSrc ) , PosDes );

    GetBodyItem( PosSrc )->Count = ResultCount;

    if( ResultCount == 0 )
    {
        GetBodyItem( PosSrc )->Init();
    }

    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------
//加一個物品到暫存區
bool RoleDataEx::AddItemtoBuf	( ItemFieldStruct& Item )
{
    GameObjDbStructEx*	OrgDB;
    OrgDB = St_GetObjDB( Item.OrgObjID );

    if( OrgDB == NULL )
        return false;

    if( OrgDB->IsKeyItem() )
    {
        int ID = OrgDB->GUID -  Def_ObjectClass_KeyItem;
        if( BaseData.KeyItem.SetFlagOn( ID ) == false )
            return false;
		if( OrgDB->KeyItem.Type == EM_KeyItemType_SkillBook )
			TempData.UpdateInfo.SkillKeyItemChange = 1;

        return true;
    }
    return TempData.ItemTemp.Push_Back( Item );
}
//------------------------------------------------------------------------------------
//刪除暫存區的物件
bool RoleDataEx::DelItemFromBuf	( ItemFieldStruct& Item )
{
    if( TempData.ItemTemp.Size() == 0 )
        return false;

    if(	Item != TempData.ItemTemp[ 0 ] )
        return false;

    TempData.ItemTemp.Pop_Front();

    return true;
}
//------------------------------------------------------------------------------------
RoleDataResultENUM    RoleDataEx::SetItemInfo_Body( ItemFieldStruct& Item , int Pos )
{
    //檢查是否超過可放置欄位
    if(  (unsigned)Pos >= (unsigned)BaseData.Body.Count )
        return EM_RoleData_PosErr;

    *GetBodyItem(Pos) = Item;

    TempData.UpdateInfo.Body = true;
    return EM_RoleData_OK;

}
RoleDataResultENUM    RoleDataEx::SetItemInfo_Bank( ItemFieldStruct& Item , int Pos )
{
    //檢查是否超過可放置欄位
    if(  (unsigned) Pos >= (unsigned)BaseData.Bank.Count )
        return EM_RoleData_PosErr;

    *GetBankItem(Pos) = Item;

    TempData.UpdateInfo.Bank = true;
    return EM_RoleData_OK;
}
RoleDataResultENUM    RoleDataEx::SetItemInfo_EQ( ItemFieldStruct& Item , int Pos )
{
    //檢查是否超過可放置欄位
    if(    (unsigned)Pos >= EM_EQWearPos_MaxCount )
        return EM_RoleData_PosErr;

    *GetEqItem(Pos) = Item;

    TempData.UpdateInfo.Eq = true;

    return EM_RoleData_OK;
}
//------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------
//給予物品
bool	RoleDataEx::GiveItem( ItemFieldStruct& Item  )
{

    //檢查此簡件是否是物品
    GameObjDbStructEx*	OrgDB;
	OrgDB = St_GetObjDB( Item.OrgObjID );
	Item.Pos = EM_ItemState_NONE;

    if( OrgDB == NULL )
        return false;

	if( OrgDB->IsNPC() )
	{
		int ItemID = St_CreateObj( Item.OrgObjID , X() , Y() , Z() , Dir() , Item.Count );
		St_AddToPartition( ItemID , BaseData.RoomID );
		return true;
	}
    if( OrgDB->IsKeyItem() )
    {
        int ID = OrgDB->GUID -  Def_ObjectClass_KeyItem;

        if( BaseData.KeyItem.GetFlag( ID ) == true )
            return false;

        if( BaseData.KeyItem.SetFlagOn( ID ) == false )
            return false;

		Net_FixKeyItemFlag( Item.OrgObjID , true );

		//重新計算資料 技能書可能改變
		if( OrgDB->KeyItem.Type == EM_KeyItemType_SkillBook )
		{
			TempData.UpdateInfo.SkillKeyItemChange = 1;
		}
        return true;
    }

    if( OrgDB->Item.Class == EM_Item_Money )
    {

        return AddBodyMoney( Item.Count );
    }

    if( Item.Count > OrgDB->MaxHeap )
        return false;

    if( Item.Count <= 0 )
        return false;

	Item.Pos = EM_ItemState_NONE;

    //加一個物品到暫存區
    if(	AddItemtoBuf	( Item ) != true )		
		return false;

    //通知玩家
    Net_ItemInBuffer( Item );

    return true;

}
//----------------------------------------------------------------------------------------
bool	RoleDataEx::GiveItem( int ItemID , int Count )
{
	if( Count <= 0 )
		return false;
	
	int TObjID , TCount;
	if( GetTreasure( ItemID , TObjID  , TCount ) == true )
	{
		ItemID = TObjID;
		Count = TCount;
	}


    ItemFieldStruct	Item;

    St_NewItemInit( Item , ItemID , 0 );

    Item.Count	  = Count;
    Item.OrgObjID = ItemID;


    return GiveItem( Item );
}
//----------------------------------------------------------------------------------------
bool	RoleDataEx::GiveItemLv( int ItemID , int Count , int LV )
{
	if( Count <= 0 )
		return false;

	int TObjID , TCount;
	if( GetTreasure( ItemID , TObjID  , TCount ) == true )
	{
		ItemID = TObjID;
		Count = TCount;
	}

	ItemFieldStruct	Item;

	St_NewItemInit( Item , ItemID , LV );
	Item.Count	  = Count;

	return GiveItem( Item );
}
//----------------------------------------------------------------------------------------
//加身上的金錢
bool RoleDataEx::AddBodyMoney( int Count )
{
	if( Count == 0 )
		return true;
    if( CheckAddBodyMoney( Count ) == false ) 
        return false;

    BaseData.Body.Money += Count;
    TempData.UpdateInfo.Money = true;

    return true;
}
//加銀行的金錢
bool RoleDataEx::AddBankMoney( int Count )
{
	if( Count == 0 )
		return true;

    if( CheckAddBankMoney( Count ) == false ) 
        return false;

    BaseData.Bank.Money += Count;
    TempData.UpdateInfo.Money = true;
    return true;
}
//----------------------------------------------------------------------------------------
//檢查加身上的金錢
bool RoleDataEx::CheckAddBodyMoney( int Count )
{
    if(     BaseData.Body.Money + Count < 0 
        ||  BaseData.Body.Money + Count > _MAX_MONEY_COUNT_ )    
        return false;
    return true;
}
//檢查加銀行的金錢
bool RoleDataEx::CheckAddBankMoney( int Count )
{
    if(     BaseData.Bank.Money + Count < 0 
        ||  BaseData.Bank.Money + Count > _MAX_MONEY_COUNT_ )    
        return false;
    return true;
}
//----------------------------------------------------------------------------------------
//計算身上有多少個交易物品
int		RoleDataEx::CalTradeItemCount()
{
    int				Count = 0;
    ItemState_ENUM	WearPos;
    int				i;

    for( i = 0 ; i < BaseData.Body.Count ; i ++ )
    {
        WearPos = BaseData.Body.Item[i].Pos;
        if(		WearPos >= EM_TRADE_ITEM1 
            &&  WearPos >= EM_TRADE_ITEM25 )
            Count++;
    }

    return Count;
}
//----------------------------------------------------------------------------------------
//計算有多少個空欄位
int		RoleDataEx::CalEmptyItemCount()
{
    int				Count = 0;
    int				i;

    for( i = 0 ; i < BaseData.Body.Count ; i ++ )
    {
        if( BaseData.Body.Item[i].IsEmpty() )
            Count++;
    }

    return Count;
}
//-----------------------------------------------------------------------------------------------
//清除所有交易中的物品 至 物品欄
void		RoleDataEx::ClsAllTradeItem()
{

    ItemState_ENUM	WearPos;
    int				i;

    for( i = 0 ; i < BaseData.Body.Count ; i ++ )
    {
        WearPos = BaseData.Body.Item[i].Pos;
        if(		WearPos >= EM_TRADE_ITEM1 
            &&  WearPos <= EM_TRADE_ITEM25 )
        {
            BaseData.Body.Item[i].Pos = EM_ItemState_NONE;
        }
    }

    TempData.UpdateInfo.Body = true;
}
//-----------------------------------------------------------------------------------------------
//清除所有交易中的物品 至 物品欄
void		RoleDataEx::DelAllTradeItem()
{

    ItemState_ENUM	WearPos;
    int				i;

    for( i = 0 ; i < BaseData.Body.Count ; i ++ )
    {
        WearPos = BaseData.Body.Item[i].Pos;
        if(		WearPos >= EM_TRADE_ITEM1 
            &&  WearPos <= EM_TRADE_ITEM25 )
        {
            BaseData.Body.Item[i].Init();
        }
    }

    TempData.UpdateInfo.Body = true;
}
//----------------------------------------------------------------------------------------
//身上物品數量計算
int     RoleDataEx::CalBodyItemCount( int OrgID )
{
    int Count  = 0;
    for( int i = 0 ; i < BaseData.Body.Count ; i ++ )
    {
        if(		BaseData.Body.Item[i].OrgObjID == OrgID 
			&&  BaseData.Body.Item[i].Pos == EM_ItemState_NONE )
            Count += BaseData.Body.Item[i].Count;
    }
    return Count;
}
int     RoleDataEx::CalBankItemCount( int OrgID )
{
    int Count  = 0;
    for( int i = 0 ; i < BaseData.Bank.Count ; i ++ )
    {
        if(		BaseData.Bank.Item[i].OrgObjID == OrgID 
			&&  BaseData.Body.Item[i].Pos == EM_ItemState_NONE )
            Count += BaseData.Bank.Item[i].Count;
    }
    return Count;
}
int     RoleDataEx::CalEqItemCount( int OrgID )
{
    int Count  = 0;
    for( int i = 0 ; i < EM_EQWearPos_MaxCount ; i ++ )
    {
        if(		BaseData.EQ.Item[i].OrgObjID == OrgID 
			&&  BaseData.Body.Item[i].Pos == EM_ItemState_NONE )
            Count += BaseData.EQ.Item[i].Count;
    }
    return Count;
}
//----------------------------------------------------------------------------------------
//刪除身上的某物品
bool     RoleDataEx::DelBodyItem( int OrgID , int Count )
{
	//撿查是否為KeyItem
	GameObjDbStructEx*	OrgDB;
	OrgDB = St_GetObjDB( OrgID );
	if( OrgDB == NULL )
		return false;
	if( OrgDB->IsKeyItem() )	
	{
		if( Count != 1 )
			return false;

		return DelKeyItem( OrgID );
	}



    if( ( unsigned int )CalBodyItemCount( OrgID ) < (unsigned int)Count )
        return false;
    
    for( int i = 0 ; i < BaseData.Body.Count ; i ++ )
    {
        if( Count == 0 )
            break;

        if(		BaseData.Body.Item[i].OrgObjID == OrgID 
			&&  BaseData.Body.Item[i].Pos == EM_ItemState_NONE )
        {
            if( Count >=  BaseData.Body.Item[i].Count )
			{
                Count -= BaseData.Body.Item[i].Count;
				BaseData.Body.Item[i].Init();
				Net_FixItemInfo_Body( i );
			}
            else
            {
                BaseData.Body.Item[i].Count -= Count;
				Net_FixItemInfo_Body( i );
                break;
			}
			
        }
    }
    return true;
}
//----------------------------------------------------------------------------------------
//刪除重要物品
bool    RoleDataEx::DelKeyItem( int OrgID )
{
    int ID = OrgID - Def_ObjectClass_KeyItem;


	GameObjDbStructEx*	OrgDB;
	OrgDB = St_GetObjDB( OrgID );

	if( OrgDB->IsKeyItem() == false )
		return false;

	if( OrgDB->KeyItem.Type == EM_KeyItemType_SkillBook )
		TempData.UpdateInfo.SkillKeyItemChange = 1;


	Net_FixKeyItemFlag( OrgID , false );
    return BaseData.KeyItem.SetFlagOff( OrgID );

}
//----------------------------------------------------------------------------------------
bool    RoleDataEx::CheckLimit( LimitStruct& Limit )
{
    //
	if( Limit.Voc._Voc != 0 && TestBit( Limit.Voc._Voc , TempData.Attr.Voc ) == false )
		return false;

    if( Level() < Limit.Level )
        return false;

    if( Limit.AGI > (int)TempData.Attr.Fin.AGI )
        return false;

    if( Limit.INT > (int)TempData.Attr.Fin.INT )
        return false;

    if( Limit.MND > (int)TempData.Attr.Fin.MND )
        return false;

    if( Limit.STR > (int)TempData.Attr.Fin.STR )
        return false;

    if( Limit.STA > (int)TempData.Attr.Fin.STA )
        return false;

    return true;
}

//取得寶物
bool RoleDataEx::GetTreasure( int TreasureID , int& ObjID  , int& Count )
{

	GameObjDbStructEx* OrgDB = St_GetObjDB( TreasureID );

	if( OrgDB == NULL )
		return false;

	if( !OrgDB->IsTreasure() )
		return false;

	
	int RValue = rand() % 10000 + ( rand() %10 * 10000 );

	for( int i = 0 ; i < OrgDB->Treasure.ItemCount ; i++ )
	{
		RValue -= OrgDB->Treasure.Item[i].Count;
		if( RValue < 0 )
		{
			ObjID = OrgDB->Treasure.Item[i].OrgID;
			Count = OrgDB->Treasure.Item[i].DropCount;
			return true;
		}
	}
	
	return false;

}

//檢查是否有某個重要物品
bool	RoleDataEx::CheckKeyItem( int KeyItemID )
{
	bool Ret = BaseData.KeyItem.GetFlag( KeyItemID - Def_ObjectClass_KeyItem );
		
	return Ret;

}