#include "RoleDataEx.h"
#include <math.h>
//計算到某目標點的長度
float   RoleDataEx::Length( float X , float Y , float Z )
{
    X -= BaseData.Pos.X;
    Y -= BaseData.Pos.Y;
    Z -= BaseData.Pos.Z;
	Y = 0;
    return sqrt( X*X + Y*Y + Z*Z);
}

float   RoleDataEx::Length( RoleDataEx* Target )
{
    return Length( Target->BaseData.Pos.X , Target->BaseData.Pos.Y , Target->BaseData.Pos.Z );
}

float   RoleDataEx::Length(  int TargetID )
{
    RoleDataEx* Target = (RoleDataEx*)St_GetRoleData( TargetID );
    if( Target == NULL )
        return 10000;
    return Length( Target->BaseData.Pos.X , Target->BaseData.Pos.Y , Target->BaseData.Pos.Z );
}

//計匴所有角色數值
void	RoleDataEx::Calculate( )
{
    TempData.Attr.Calculate();
}

//-----------------------------------------------------------------------------------------------
//初始化角色計算數值
void	RoleDataEx::InitCal( )
{
    //----------------------------------------------------------------------
    BaseAbilityStruct*		Ability;
//    TempData.Attr.Skill	= &BaseData.Skill;			//技能資料
    Ability = TempData.Attr.Ability = &BaseData.AbilityList[ BaseData.Voc ];
	if( IsNPC() )
		TempData.Attr.SkillValue = &TempData.Attr.MaxSkillValue;
	else
		TempData.Attr.SkillValue = &BaseData.SkillValue;

	if( BaseData.Voc_Sub == BaseData.Voc )
		BaseData.Voc_Sub = EM_Vocation_None;

    //基本數值
    TempData.Attr.Race		= BaseData.Race;
    TempData.Attr.Sex		= BaseData.Sex; 
    TempData.Attr.Voc   	= BaseData.Voc;
    TempData.Attr.Voc_Sub   = BaseData.Voc_Sub;



    if( Ability->Level == 0 )
        Ability->Level = 1;

    TempData.Attr.Level = Ability->Level;

    if( EM_Vocation_None == BaseData.Voc_Sub )
    {
        TempData.Attr.Level_Sub = 0;
    }
    else
    {
        TempData.Attr.Level_Sub = BaseData.AbilityList[ BaseData.Voc_Sub ].Level;
        TempData.Attr.Level_Sub = __min( TempData.Attr.Level_Sub , ( Ability->Level ) );
    }

    GameObjDbStructEx*		OrgDB = St_GetObjDB( BaseData.ItemInfo.OrgObjID );
    if( OrgDB == NULL )
        return;


    if( !OrgDB->IsNPC() )
    {
        InitMagicBook();
        //設定備動技能
        ReSetPassiveSkill();
    }

    //記算Table 重設
    TempData.Attr.ReSetTable();
    TempData.Attr.Table.MaxExp = GetLVExp();

    if( IsNPC() )
        TempData.Attr.Bas.MoveSpeed_Per = (float)OrgDB->NPC.MoveSpeed ;
    else
        TempData.Attr.Bas.MoveSpeed_Per = 100;


    ReCalculateMagicAndEQ( );

    Calculate();
    //----------------------------------------------------------------------
    //(暫時)
    BaseData.HP = (int)TempData.Attr.Fin.MaxHP;
    BaseData.MP = (int)TempData.Attr.Fin.MaxMP;
    //----------------------------------------------------------------------

}
//-----------------------------------------------------------------------------------------------
//檢查角色資料是否有問題，如果有自動更正
void    RoleDataEx::InitCheckRoleData( )
{
    int i;
    GameObjDbStructEx*		OrgDB;//	= St_GetObjDB( Field->OrgObjID );
    //hp mp
    if( BaseData.HP <= 0 )
        BaseData.HP = 1;
    if( BaseData.MP < 0 )
        BaseData.MP = 0;

    //物品
    if( BaseData.Body.Count < 0 )
        BaseData.Body.Count = 0;
    if( BaseData.Body.Count > _MAX_BODY_COUNT_ )
        BaseData.Body.Count = _MAX_BODY_COUNT_;

    for( i = 0 ; i < BaseData.Body.Count ; i++ )    
    {
        ItemFieldStruct& Field = BaseData.Body.Item[i];
        if( Field.Count <= 0)
        {
            Field.Init();
            continue;
        }

        OrgDB = St_GetObjDB( Field.OrgObjID );
        if( OrgDB == NULL )
        {
            Field.Init();
            continue;
        }
        if( OrgDB->MaxHeap < Field.Count )
            Field.Count = OrgDB->MaxHeap;

    }
    //銀行
    if( BaseData.Bank.Count < 0 )
        BaseData.Bank.Count = 0;
    if( BaseData.Bank.Count > _MAX_BODY_COUNT_ )
        BaseData.Bank.Count = _MAX_BODY_COUNT_;

    for( i = 0 ; i < BaseData.Bank.Count ; i++ )    
    {
        ItemFieldStruct& Field = BaseData.Bank.Item[i];
        if( Field.Count <= 0)
        {
            Field.Init();
            continue;
        }

        OrgDB = St_GetObjDB( Field.OrgObjID );
        if( OrgDB == NULL )
        {
            Field.Init();
            continue;
        }
        if( OrgDB->MaxHeap < Field.Count )
            Field.Count = OrgDB->MaxHeap;

    }
    //裝備(暫時)   
    for( i = 0 ; i < EM_EQWearPos_MaxCount ; i++ )    
    {
        ItemFieldStruct& Field = BaseData.EQ.Item[i];
        if( Field.Count <= 0)
        {
            Field.Init();
            continue;
        }

        OrgDB = St_GetObjDB( Field.OrgObjID );
        if( OrgDB == NULL )
        {
            Field.Init();
            continue;
        }
        if( OrgDB->MaxHeap < Field.Count )
            Field.Count = OrgDB->MaxHeap;

    }
	/*
    //技能
    for( i = 0 ; i < EM_Max_Vocation ; i++ )
    {
        BaseAbilityStruct& Abi = BaseData.AbilityList[i];
        for( int j = 0 ; j < _MAX_NormalSkill_COUNT_ ; j++ )
        {
            if( Abi.MagicPoint[j] < 0 )
                Abi.MagicPoint[j] = 0;
            else if( Abi.MagicPoint[j] > 10 )
                Abi.MagicPoint[j] = 10;
        }
    }*/
}
//-----------------------------------------------------------------------------------------------
//設定物品裝備資訊
void    RoleDataEx::ResetItemInfo( )
{

}
//-----------------------------------------------------------------------------------------------

//記算法術與裝備
void    RoleDataEx::ReCalculateMagicAndEQ( )
{
	ItemFieldStruct* Item;
	int		i;

    TempData.Attr.Init_MidValue();

	//記算被動技能
	for( i = 0 ; i < TempData.PassiveSkill.Size() ; i++ )
	{
		WearObject( TempData.PassiveSkill[i] );
	}
	//-------------------------------------------------------------------------
	//先計算裝備能力
	TempData.Attr.CalWearSkill( );
	map< int , int > SuitIDList;
	map< int , int >::iterator Iter;

	//計算套裝資料
	for( i = 0 ; i < EM_EQWearPos_MaxCount ; i++ )
	{
		Item = GetEqItem( i );
		GameObjDbStructEx* OrgDB = St_GetObjDB( Item->OrgObjID );
		
		if( OrgDB == NULL )
			continue;

		if( CheckEQLimit( OrgDB) == false )
		{
			Item->Mode.EQCannotEquipment = true;
			continue;
		}
		else
		{
			Item->Mode.EQCannotEquipment = false;
		}

		Item = GetEqItem( i );
		WearEQ( Item , i );

		if( OrgDB->Item.SuitID == 0 )
			continue;		

		SuitIDList[ OrgDB->Item.SuitID ] ++;
	}

	for( Iter = SuitIDList.begin() ; Iter != SuitIDList.end() ; Iter++ )
	{
		if( Iter->second <= 1 )
			continue;

		WearSuit( Iter->first , Iter->second );
	}
	//-------------------------------------------------------------------------

	FixWeaponType();

    //計算法術Buff
    for( i = 0 ; i < BaseData.Buff.Size() ; i++ )
    {
        WearObject( BaseData.Buff[i].BuffID );
    }  

}
//-----------------------------------------------------------------------------------------------
//貝份定時檢查的資料
void    RoleDataEx::InitOnTimeCheck( )
{

}
//-----------------------------------------------------------------------------------------------
bool	RoleDataEx::WearEQ( ItemFieldStruct* Field , int Pos )
{
    if( Field == NULL )
        return false;

    GameObjDbStructEx*		OrgDB	= St_GetObjDB( Field->OrgObjID );
    
	if( OrgDB == NULL )
		return false;

    if( OrgDB->IsWeapon() == false )
        Pos = -1;

    if( Pos == EM_EQWearPos_SecondHand )
    {
        TempData.Attr.SecWeaponType = OrgDB->Item.WeaponType;
		TempData.Attr.SecAttackRange = OrgDB->Item.AttackRange;
    }
	else if( Pos == EM_EQWearPos_MainHand )
	{
		TempData.Attr.MainWeaponType = OrgDB->Item.WeaponType;
		TempData.Attr.MainAttackRange = OrgDB->Item.AttackRange;
	}

    if ( WearObject( OrgDB , Pos ) == false )
        return false;
    
    WearObject( Field->Inherent , Pos );

    WearObject( Field->Rune[0] , Pos );
    WearObject( Field->Rune[1] , Pos );
    WearObject( Field->Rune[2] , Pos );
    WearObject( Field->Rune[3] , Pos ); 
    
    return true;
}

bool	RoleDataEx::WearSuit( int SuitID , int Count )
{

	GameObjDbStructEx*    OrgDB = St_GetObjDB( SuitID );
    RoleValueData&		  Attr = TempData.Attr;

	if( OrgDB == NULL || OrgDB->IsSuit() == false )
		return false;

	if( Count <= 1 || Count > 10 )
		return false;

	for( int i = 0 ; i < 10 ; i++ )
	{
		WearEqTypeENUM  EqType		= OrgDB->Suit.SuitValue[ Count - 2 ].EqType[ i ] ;
		int             EqTypeValue	= OrgDB->Suit.SuitValue[ Count - 2 ].EqTypeValue[ i ];

		Attr.Mid.Body[ EqType ] += EqTypeValue;
	}

	return true;
}

bool	RoleDataEx::WearObject( int OrgDBID , int Pos  )
{
    if( OrgDBID == 0 )
        return false;

    GameObjDbStructEx*    OrgDB = St_GetObjDB( OrgDBID );
    return WearObject( OrgDB , Pos );
}

bool	RoleDataEx::WearObject( GameObjDbStructEx* OrgDB , int Pos )
{
    if( OrgDB->IsEmpty() )
        return  false;

    RoleValueData& Attr = TempData.Attr;
    GameObjectWearEqStruct* Ability;

    switch( OrgDB->Classification )
    {
    case EM_ObjectClass_Item:
        Ability = &OrgDB->Item.Ability;
        break;
    case EM_ObjectClass_MagicBase:
        {
            Ability = &OrgDB->MagicBase.Ability;
            Attr.Effect._Value = Attr.Effect._Value | OrgDB->MagicBase.Effect._Value;
			Attr.AssistMagicSetting._Type = Attr.AssistMagicSetting._Type | OrgDB->MagicBase.Setting._Type;
        }
        break;
	case EM_ObjectClass_Attribute:
		Ability = &OrgDB->Attirbute.Ability;
		break;
    default:
        return false;
    }

	int Type;
	int Value;
	switch( Pos )
	{
		case EM_EQWearPos_MainHand:
			{
				for( int i = 0 ; i < Max_WearEqType_Count ; i++ )
				{
					Type	= Ability->EqType[ i ];
					Value	= Ability->EqTypeValue[i];
					switch( Type )
					{
					case EM_WearEqType_HitRate	    		:	//命中率
						Attr.Mid.Main_HitRate += Value;
						break;
					case EM_WearEqType_CritRate	    		:   //致命一擊率
						Attr.Mid.Main_CriticalHit += Value;
						break;
					case EM_WearEqType_AtkSpeed	    		:   //攻擊速度
						Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_DMG           		:   //武器威力 所有近戰或遠程 ( DMG )
						Attr.Mid.Main_DMG += Value;
						break;
						//尚未實作
					case EM_WearEqType_DMG_AllWeapon		:	//近戰武器威力 所有
						Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Unarmed			:	//近戰武器威力 空手
						if( Attr.SecWeaponType == EM_Weapon_Unarmed )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Blade     		:	//近戰武器威力 劍
						if( Attr.SecWeaponType == EM_Weapon_Blade )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Dagger    		:	//近戰武器威力 匕首
						if( Attr.SecWeaponType == EM_Weapon_Dagger )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Wand      		:	//近戰武器威力 權杖
						if( Attr.SecWeaponType == EM_Weapon_Wand )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Axe       		:	//近戰武器威力 斧
						if( Attr.SecWeaponType == EM_Weapon_Axe )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Bludgeon  		:	//近戰武器威力 鎚棍棒
						if( Attr.SecWeaponType == EM_Weapon_Bludgeon )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Claymore  		:	//近戰武器威力 雙手劍
						if( Attr.SecWeaponType == EM_Weapon_Claymore )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Staff     		:	//近戰武器威力 杖
						if( Attr.SecWeaponType == EM_Weapon_Staff )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_2H_Axe    		:	//近戰武器威力 雙手斧
						if( Attr.SecWeaponType == EM_Weapon_2H_Axe )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_2H_Hammer 		:	//近戰武器威力 雙手鎚
						if( Attr.SecWeaponType == EM_Weapon_2H_Hammer )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Polearm			:	//近戰武器威力 槍(長矛)
						if( Attr.SecWeaponType == EM_Weapon_Polearm )
							Attr.Mid.Main_DMG_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_AllWeapon:	//近戰武器速度 所有				
						Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Unarmed	:	//近戰武器速度 空手
						if( Attr.SecWeaponType == EM_Weapon_Unarmed )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Blade    :	//近戰武器速度 劍
						if( Attr.SecWeaponType == EM_Weapon_Blade )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Dagger   :	//近戰武器速度 匕首
						if( Attr.SecWeaponType == EM_Weapon_Dagger )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Wand     :	//近戰武器速度 權杖
						if( Attr.SecWeaponType == EM_Weapon_Wand )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Axe      :	//近戰武器速度 斧
						if( Attr.SecWeaponType == EM_Weapon_Axe )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Bludgeon :	//近戰武器速度 鎚棍棒
						if( Attr.SecWeaponType == EM_Weapon_Bludgeon )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Claymore :	//近戰武器速度 雙手劍
						if( Attr.SecWeaponType == EM_Weapon_Claymore )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Staff    :	//近戰武器速度 杖
						if( Attr.SecWeaponType == EM_Weapon_Staff )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_2H_Axe   :	//近戰武器速度 雙手斧
						if( Attr.SecWeaponType == EM_Weapon_2H_Axe )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_2H_Hammer:	//近戰武器速度 雙手鎚
						if( Attr.SecWeaponType == EM_Weapon_2H_Hammer )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Polearm	:	//近戰武器速度 槍(長矛)
						if( Attr.SecWeaponType == EM_Weapon_Polearm )
							Attr.Mid.Main_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_WeaponAttack_Earth  	:   //武器附加屬性攻擊 地
						Attr.Mid.Main_MagicAtk[ EM_MagicResist_Earth ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Water  	:   //武器附加屬性攻擊 水
						Attr.Mid.Main_MagicAtk[ EM_MagicResist_Water ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Fire   	:   //武器附加屬性攻擊 火
						Attr.Mid.Main_MagicAtk[ EM_MagicResist_Fire ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Wind   	:   //武器附加屬性攻擊 風
						Attr.Mid.Main_MagicAtk[ EM_MagicResist_Wind ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Light  	:   //武器附加屬性攻擊 光
						Attr.Mid.Main_MagicAtk[ EM_MagicResist_Light ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Darkness:   //武器附加屬性攻擊 闇						
						Attr.Mid.Main_MagicAtk[ EM_MagicResist_Darkness ] += Value;
						break;
					default:
						{
							Attr.Mid.Body[Type ] += Value;
						}
						break;
					}					 
				}	
			}
			break;
		case EM_EQWearPos_SecondHand:
			{			
				for( int i = 0 ; i < Max_WearEqType_Count ; i++ )
				{
					Type	= Ability->EqType[ i ];
					Value	= Ability->EqTypeValue[i];
					switch( Type )
					{

					case EM_WearEqType_HitRate	    		:	//命中率
						Attr.Mid.Sec_HitRate += Value;
						break;
					case EM_WearEqType_CritRate	    		:   //致命一擊率
						Attr.Mid.Sec_CriticalHit += Value;
						break;
					case EM_WearEqType_AtkSpeed	    		:   //攻擊速度
						Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_DMG           		:   //武器威力 所有近戰或遠程 ( DMG )
						Attr.Mid.Sec_DMG += Value;
						break;
					//尚未實作
					case EM_WearEqType_DMG_AllWeapon		:	//近戰武器威力 所有
						Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Unarmed			:	//近戰武器威力 空手
						if( Attr.SecWeaponType == EM_Weapon_Unarmed )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Blade     		:	//近戰武器威力 劍
						if( Attr.SecWeaponType == EM_Weapon_Blade )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Dagger    		:	//近戰武器威力 匕首
						if( Attr.SecWeaponType == EM_Weapon_Dagger )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Wand      		:	//近戰武器威力 權杖
						if( Attr.SecWeaponType == EM_Weapon_Wand )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Axe       		:	//近戰武器威力 斧
						if( Attr.SecWeaponType == EM_Weapon_Axe )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Bludgeon  		:	//近戰武器威力 鎚棍棒
						if( Attr.SecWeaponType == EM_Weapon_Bludgeon )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Claymore  		:	//近戰武器威力 雙手劍
						if( Attr.SecWeaponType == EM_Weapon_Claymore )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Staff     		:	//近戰武器威力 杖
						if( Attr.SecWeaponType == EM_Weapon_Staff )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_2H_Axe    		:	//近戰武器威力 雙手斧
						if( Attr.SecWeaponType == EM_Weapon_2H_Axe )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_2H_Hammer 		:	//近戰武器威力 雙手鎚
						if( Attr.SecWeaponType == EM_Weapon_2H_Hammer )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_DMG_Polearm			:	//近戰武器威力 槍(長矛)
						if( Attr.SecWeaponType == EM_Weapon_Polearm )
							Attr.Mid.Sec_DMG_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_AllWeapon:	//近戰武器速度 所有				
						Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Unarmed	:	//近戰武器速度 空手
						if( Attr.SecWeaponType == EM_Weapon_Unarmed )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Blade    :	//近戰武器速度 劍
						if( Attr.SecWeaponType == EM_Weapon_Blade )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Dagger   :	//近戰武器速度 匕首
						if( Attr.SecWeaponType == EM_Weapon_Dagger )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Wand     :	//近戰武器速度 權杖
						if( Attr.SecWeaponType == EM_Weapon_Wand )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Axe      :	//近戰武器速度 斧
						if( Attr.SecWeaponType == EM_Weapon_Axe )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Bludgeon :	//近戰武器速度 鎚棍棒
						if( Attr.SecWeaponType == EM_Weapon_Bludgeon )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Claymore :	//近戰武器速度 雙手劍
						if( Attr.SecWeaponType == EM_Weapon_Claymore )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Staff    :	//近戰武器速度 杖
						if( Attr.SecWeaponType == EM_Weapon_Staff )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_2H_Axe   :	//近戰武器速度 雙手斧
						if( Attr.SecWeaponType == EM_Weapon_2H_Axe )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_2H_Hammer:	//近戰武器速度 雙手鎚
						if( Attr.SecWeaponType == EM_Weapon_2H_Hammer )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_AttackSpeed_Polearm	:	//近戰武器速度 槍(長矛)
						if( Attr.SecWeaponType == EM_Weapon_Polearm )
							Attr.Mid.Sec_ATKSpeed_Per += Value;
						break;
					case EM_WearEqType_WeaponAttack_Earth  	:   //武器附加屬性攻擊 地
						Attr.Mid.Sec_MagicAtk[ EM_MagicResist_Earth ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Water  	:   //武器附加屬性攻擊 水
						Attr.Mid.Sec_MagicAtk[ EM_MagicResist_Water ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Fire   	:   //武器附加屬性攻擊 火
						Attr.Mid.Sec_MagicAtk[ EM_MagicResist_Fire ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Wind   	:   //武器附加屬性攻擊 風
						Attr.Mid.Sec_MagicAtk[ EM_MagicResist_Wind ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Light  	:   //武器附加屬性攻擊 光
						Attr.Mid.Sec_MagicAtk[ EM_MagicResist_Light ] += Value;
						break;
					case EM_WearEqType_WeaponAttack_Darkness:   //武器附加屬性攻擊 闇						
						Attr.Mid.Sec_MagicAtk[ EM_MagicResist_Darkness ] += Value;
						break;
					default:
						{
							Attr.Mid.Body[Type ] += Value;
						}
						break;
					}					 
				}	 
			}
			break;
		default:
			{
				//而外計算各類裝備的防禦值
				if( OrgDB->IsArmor() )
				{
					for( int i = 0 ; i < Max_WearEqType_Count ; i++ )
					{
						if( Ability->EqType[ i ] == EM_WearEqType_DEF )
						{
							Attr.Mid.Def[ OrgDB->Item.ArmorType ] += Ability->EqTypeValue[i];
						}					
					}
				}

				for( int i = 0 ; i < Max_WearEqType_Count ; i++ )
				{
					Attr.Mid.Body[ Ability->EqType[ i ] ] += Ability->EqTypeValue[i];
				}
			}
			break;
	}
 
    return true;
}

//-----------------------------------------------------------------------------------------------
//計算兩者關係好壞值(用來決定攻擊與幫助的優先次序)
int		RoleDataEx::CalRelation( RoleDataEx* Target )
{
    //(暫時)
    if( Target->TempData.Sys.GUID != TempData.Sys.GUID )
        return 0;

    int	L = int( Length( Target ) );

    if( L > 500 )
        return 0;

    return L - 500 ;
}
//-----------------------------------------------------------------------------------------------
//基本仇恨值
int		RoleDataEx::BaseHate( RoleData* Target )
{
    int	DLV = Target->TempData.Attr.Ability->Level - TempData.Attr.Ability->Level;
    DLV = __max( 0  , DLV );
    DLV = __min( 10 , DLV );

    return HateTable[BaseData.Race][Target->BaseData.Race] + DLV * 5;
}
//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------
//他人影響 加HP 或加MP
void	RoleDataEx::AddHP( RoleDataEx* Target ,  int DHP )
{
    if( DHP == 0 )
        return;

    if( IsDead() )
        return;

    if( BaseData.HP+DHP < 0  )
        DHP = int( BaseData.HP * -1 );  
    else if( BaseData.HP+DHP > TempData.Attr.Fin.MaxHP )
        DHP = int( TempData.Attr.Fin.MaxHP - BaseData.HP);

    BaseData.HP += DHP;

    if( DHP == 0 )
        return;

    if( BaseData.HP <= 0 )
        St_PrcoessDead( this , Target );

    if( Target == NULL )
        return;

    CalHate( Target , DHP*-1 );		

}
//-----------------------------------------------------------------------------------------------
void	RoleDataEx::AddMP( RoleDataEx* Target ,  int DMP )
{
    if( DMP == 0 )
        return;
    if( IsDead() )
        return;

    BaseData.MP += DMP;

    if( BaseData.MP > TempData.Attr.Fin.MaxMP )
        BaseData.MP = int( TempData.Attr.Fin.MaxMP );

    if( Target == NULL )
        return;

    CalHate( Target , DMP*-1 );		

}
//-----------------------------------------------------------------------------------------------
void	RoleDataEx::AddSP( RoleDataEx* Target ,  int DSP )
{
    if( DSP == 0 )
        return;

    if( IsDead() )
        return;

    BaseData.SP += DSP;

    if( BaseData.SP > TempData.Attr.Fin.MaxSP )
        BaseData.SP = int( TempData.Attr.Fin.MaxSP );

	if( BaseData.SP < 0 )
		BaseData.SP = 0;

    if( Target == NULL )
        return;

    CalHate( Target , DSP*-1 );		

}
//-----------------------------------------------------------------------------------------------
void	RoleDataEx::AddSP_Sub( RoleDataEx* Target ,  int DSP )
{
	if( DSP == 0 )
		return;

	if( IsDead() )
		return;

	BaseData.SP_Sub += DSP;

	if( BaseData.SP_Sub > TempData.Attr.Fin.MaxSP_Sub )
		BaseData.SP_Sub = int( TempData.Attr.Fin.MaxSP_Sub );

	if( Target == NULL )
		return;

	if( BaseData.SP_Sub < 0 )
		BaseData.SP_Sub = 0;

	CalHate( Target , DSP*-1 );		

}
//-----------------------------------------------------------------------------------------------
void    RoleDataEx::OnTimeCalHate( )
{
    if( IsAttack() == false )
        return;

    //三十秒處理一次
    if( ClockMod( 300 ) )
        return;

    int		i; 
    for( i = 0 ; i < TempData.NPCHate.Hate.Size() ; i++ )
    {
        TempData.NPCHate.Hate[i].HatePoint /= 2 ;
    }

    TempData.NPCHate.MaxHitPoint/=3;

}
void RoleDataEx::ClearHate()
{

    RoleDataEx*     Target;
//    NPCHateStruct*	NPCHate;
    int             TempID;

    for( int i = 0 ; i < TempData.NPCHate.Hate.Size() ; i++ )
    {
        TempID = TempData.NPCHate.Hate[i].ItemID;
//        if( TempID == -1 )
//            break;
        TempData.NPCHate.Hate[i].Init();

        Target = (RoleDataEx*)St_GetRoleData( TempID );
        if( Target == NULL || Target->IsNPC() )
            continue;
        
        Target->FixAttackMode();
    }
    TempData.NPCHate.Hate.Clear();

}
/*
void RoleDataEx::ClearHate()
{
    if( IsPlayer() )
    {
        ClearHate_Player( );
    }
    else
    {
        ClearHate_NPC( );
    }
}
//-----------------------------------------------------------------------------------------------
void RoleDataEx::ClearHate_NPC( )
{
    RoleDataEx*     Target;
    NPCHateStruct*	NPCHate;
    int             TempID;

    for( int i = 0 ; i < _MAX_HATELIST_SIZE_ ; i++ )
    {
        TempID = TempData.NPCHate.Hate[i].ItemID;
        if( TempID == -1 )
            break;
        TempData.NPCHate.Hate[i].Init();


        Target = (RoleDataEx*)St_GetRoleData( TempID );
        if( Target == NULL )
            continue;

        for( int j = 0 ; j < _MAX_HATELIST_SIZE_ ; j++ )
        {
            if( Target->TempData.NPCHate[j].ItemID == TempID )
            {
                Target->TempData.NPCHate[j].Init();
                Target->TempData.NPCHate[j].ItemID = 0;
                Target->TempData.EnemyCount--;
                if( Target->TempData.EnemyCount == 0 )
                    Target->AttackMode( false );
                break;
            }
        }
    }

    TempData.EnemyCount = 0;
    AttackMode( false );
}

void RoleDataEx::ClearHate_Player( )
{
    RoleDataEx*     Target;
    NPCHateStruct*	NPCHate;
    int             TempID;

    for( int i = 0 ; i < _MAX_HATELIST_SIZE_ ; i++ )
    {
        TempID = TempData.NPCHate.Hate[i].ItemID;
        if( TempID == -1 )
            break;

        Target = (RoleDataEx*)St_GetRoleData( TempID );
        if( Target == NULL )
            continue;

        TempData.EnemyCount--;

        for( int j = 0 ; j < _MAX_HATELIST_SIZE_ ; j++ )
        {
            if( Target->TempData.NPCHate[j].ItemID == TempID )
            {
                Target->TempData.NPCHate[j].Init();
                Target->TempData.NPCHate[j].ItemID = 0;
                Target->TempData.EnemyCount--;
                if( Target->TempData.EnemyCount == 0 )
                    Target->AttackMode( false );

                TempData.EnemyCount--;
   
                break;
            }
        }
    }

    if( TempData.EnemyCount == 0 )
        AttackMode( false );

}
*/

//-----------------------------------------------------------------------------------------------
//增加某一個人的仇恨值( 此怪物被 npc 或 pc 打)
//並做攻擊目標的轉換
bool	RoleDataEx::CalHate( RoleDataEx* Att , int Damage )
{
    RoleDataEx* Target = this;

    if( Att == this )
        return false;

    if( Damage == 0 ) 
        return false;


    if( Damage < 0 )
    {
        if( this->IsAttack() == false )
            return false;
        Damage *= -1;
        Target = (RoleDataEx*)St_GetRoleData( TempData.AI.TargetID );
        if( Target == NULL )
            return false;
    }

    //取得id資訊位置	
    NPCHateStruct*	NPCHate = GetHatePos( Att->GUID() , Att->DBID() ); 

	if(		Target->CheckStrikback() == true ) 
	{
		Att->IsAttackMode( true );
		IsAttackMode( true );
	}

    NPCHate->HatePoint += Damage;
    NPCHate->HitPoint  += Damage;
    
    if( IsNPC() )
    {
        //如果沒有在攻擊狀態 就反擊
        if(  Target->IsAttack() == false && Target->CheckStrikback() )
        {
            Target->AttackTarget( Att->GUID() );
        }
		else
		{
			Target->TempData.AI.TargetID		    = Att->GUID();
		}

        //攻擊超過一定量轉變目標
        if( TempData.NPCHate.MaxHitPoint < NPCHate->TotalHatePoint() ) 
        {
            Target->TempData.NPCHate.MaxHitPoint	= NPCHate->TotalHatePoint();
            Target->TempData.AI.TargetID		    = Att->GUID();
        }
    }   
    
    RoleDataEx* AttOwner = St_GetRoleData( Att->OwnerGUID() );
    if( AttOwner != NULL )
    {
        Target->CalHate( AttOwner , Damage );
    }

    return true;

}

bool	RoleDataEx::CalTempHate( RoleDataEx* Att , int Hate )
{
	RoleDataEx* Target = this;

	if( Att == this )
		return false;

	if( Hate == 0 ) 
		return false;

	//取得id資訊位置	
	NPCHateStruct*	NPCHate = GetHatePos( Att->GUID() , Att->DBID() ); 

	NPCHate->TempHatePoint += Hate;

	if( IsNPC() && Hate > 0 )
	{
		Att->IsAttackMode( true );
		IsAttackMode( true );

		//如果沒有在攻擊狀態 就反擊
		if(  Target->IsAttack() == false && Target->CheckStrikback() )
		{
			Target->AttackTarget( Att->GUID() );
		}
		else
		{
			Target->TempData.AI.TargetID		    = Att->GUID();
		}

		//攻擊超過一定量轉變目標
		if( TempData.NPCHate.MaxHitPoint < NPCHate->TotalHatePoint() ) 
		{
			Target->TempData.NPCHate.MaxHitPoint	= NPCHate->TotalHatePoint();
			Target->TempData.AI.TargetID		    = Att->GUID();
		}
	}   

	return true;
}
//-----------------------------------------------------------------------------------------------
bool	RoleDataEx::ClearHate_One( int PlayerID )
{
	int PlayerPos = -1;
	int i;

	for( i = 0 ; i < TempData.NPCHate.Hate.Size() ; i++)
	{
		int TempID = TempData.NPCHate.Hate[i].ItemID;

		if( TempID == PlayerID )
		{
			PlayerPos = i;
			break;
		}
	}

	if( PlayerPos != -1 )
	{
		TempData.NPCHate.Hate[PlayerPos] = TempData.NPCHate.Hate.Back();
		TempData.NPCHate.Hate.Pop_Back();
		return true;
	}
	
	return false;
}
//-----------------------------------------------------------------------------------------------
//計算攻擊模式
ATTACK_DMGTYPE_ENUM RoleDataEx::CheckAtkDmgType( RoleDataEx* Target , AttackHandTypeENUM Type )
{
	//////////////////////////////////////////////////////////////////////////
	if( CheckPhyAttack( Target ) == false )
	{
		return EM_ATTACK_DMGTYPE_NO_EFFECT;
	}
	//////////////////////////////////////////////////////////////////////////
    RoleValueData&	TAttr = Target->TempData.Attr;
    RoleValueData&	OAttr = TempData.Attr;
    int DLV = Level() - Target->Level();
    if( DLV > 20 )
        DLV = 20;

	if( DLV < -20 )
		DLV = -20;

	//////////////////////////////////////////////////////////////////////////
	//	命中率計算
	//////////////////////////////////////////////////////////////////////////
	int		HitRate		= 0;
	int		DodgeRate	= 0;
	int		MissRate	= 0;

	switch( Type )
	{
	case EM_AttackHandType_Main:
		//Rate = int(  OAttr->Fin.Main_HitRate - TAttr->Fin.DodgeRate  + DLV * RoleValueData::FixArg.Miss_DLV );
		HitRate		= int( OAttr.Fin.Main_HitRate + (DLV * RoleValueData::FixArg.Miss_DLV)/2 );
		DodgeRate	= int( TAttr.Fin.DodgeRate    - (DLV * RoleValueData::FixArg.Miss_DLV)/2 );
		break;
	case EM_AttackHandType_Second:
		//Rate = int(  OAttr->Fin.Sec_HitRate - TAttr->Fin.DodgeRate  + DLV * RoleValueData::FixArg.Miss_DLV );
		HitRate		= int( OAttr.Fin.Sec_HitRate	+ (DLV * RoleValueData::FixArg.Miss_DLV)/2  );
		DodgeRate	= int( TAttr.Fin.DodgeRate		- (DLV * RoleValueData::FixArg.Miss_DLV)/2		);

		break;
	case EM_AttackHandType_None:
		return EM_ATTACK_DMGTYPE_NO_EFFECT;
	}
	
	float WeaponSkill;
	switch(Type)
	{
	case EM_AttackHandType_Main:
		WeaponSkill = GetWeaponSkillValue( OAttr.MainWeaponType );
		break;
	case EM_AttackHandType_Second:
		WeaponSkill = GetWeaponSkillValue( OAttr.SecWeaponType );
		break;
	}

	float TargetDefSkill = Target->GetSkillValue( EM_SkillValueType_Define );

	float DSkill = WeaponSkill - TargetDefSkill;

	HitRate		= HitRate	+ int( DSkill * RoleValueData::FixArg.Miss_Skill_DLV );
	DodgeRate	= DodgeRate - int( DSkill * RoleValueData::FixArg.Miss_Skill_DLV );
	MissRate	= 100 - HitRate;

	if( MissRate < 0 )
		MissRate = 5;

	if( HitRate < 20 )
		HitRate = 20;
	
	if( DodgeRate < 0 )
		DodgeRate = 0;

	if( DodgeRate > 50 )
		DodgeRate = 50;

	int Total = int( HitRate + DodgeRate + MissRate )+1;
	float	RandValue = float( rand() % Total );

	if( RandValue < DodgeRate )
	{
		return EM_ATTACK_DMGTYPE_DODGE;
	}

	RandValue -= DodgeRate;
	if( RandValue < MissRate )
	{
		return EM_ATTACK_DMGTYPE_MISS;
	}
	//////////////////////////////////////////////////////////////////////////
    //檢查是否被革擋
    if( TAttr.Fin.ParryRate >= rand() % 100 )
    {
        return EM_ATTACK_DMGTYPE_HALF;
    }
    
	//////////////////////////////////////////////////////////////////////////
	//　　Critial 
	//////////////////////////////////////////////////////////////////////////

    if( Type == EM_AttackHandType_Main )
    {
		float  CritRate = OAttr.Fin.Main_CriticalHit + DLV * RoleValueData::FixArg.Crit_DLV;
		if( CritRate > 50 )
			CritRate = 50;

        if( CritRate >= rand() % 100 )
        {
            return EM_ATTACK_DMGTYPE_DOUBLE;
        }
    }
    else
    {
		float  CritRate = OAttr.Fin.Sec_CriticalHit + DLV * RoleValueData::FixArg.Crit_DLV;
		if( CritRate > 50 )
			CritRate = 50;

        if( CritRate >= rand() % 100 )
        {
            return EM_ATTACK_DMGTYPE_DOUBLE;
        }
    }

    return EM_ATTACK_DMGTYPE_NORMAL;
}
//-----------------------------------------------------------------------------------------------
//增減 Exp
void    RoleDataEx::Addexp( int Exp )
{
    if( Exp == 0 )
        return ;

    TempData.UpdateInfo.ExpChange = true;
    TempData.Attr.Ability->EXP += Exp ;
    if( TempData.Attr.Ability->EXP < 0 )
        TempData.Attr.Ability->EXP = 0;

    //檢查是否升級
    if( GetLVExp() <= TempData.Attr.Ability->EXP )
    {
        //升級處理
        if( _MAX_LEVEL_ > TempData.Attr.Ability->Level )
        {
            AddValue( EM_RoleValue_LV           , 1 );
            AddValue( EM_RoleValue_Point        , 1 );
//            AddValue( EM_RoleValue_SkillPoint   , 1 );

            //通知週圍升級
            Net_NotifyLvUp();

            TempData.Attr.ReSetTable();
            Calculate();

            BaseData.HP = (int)TempData.Attr.Fin.MaxHP;
            BaseData.MP = (int)TempData.Attr.Fin.MaxMP;

            Net_MaxHPMaxMPMaxSP();
            Net_HPMPSP();

            TempData.Attr.Ability->EXP	= 0;

            TempData.UpdateInfo.Recalculate = true;
        }
        else
        {
            TempData.Attr.Ability->EXP = 0;
            return;
        }
    }

    Net_FixRoleValue( EM_RoleValue_EXP , (float)TempData.Attr.Ability->EXP );
}

float   RoleDataEx::GetValue( MagicAttackCalENUM Type )
{
    switch( Type )
    {
    case EM_MagicAttackCal_None:    
        return 1;
        break;
    case EM_MagicAttackCal_MPow:    
        return TempData.Attr.Fin.MPow;
        break;
    case EM_MagicAttackCal_Weapon:  
        return TempData.Attr.Fin.Main_DMG;
        break;
    case EM_MagicAttackCal_Shoot:
        return 1;
        break;
    case EM_MagicAttackCal_Throw:   
        return 1;
        break;
    case EM_MagicAttackCal_INT:     
        return TempData.Attr.Fin.INT;
        break;
    case EM_MagicAttackCal_STR:     
        return TempData.Attr.Fin.STR;
        break;
    case EM_MagicAttackCal_AGI:     
        return TempData.Attr.Fin.AGI;
        break;
    case EM_MagicAttackCal_STA:
        return TempData.Attr.Fin.STA;
        break;
    case EM_MagicAttackCal_MND:
        return TempData.Attr.Fin.MND;
        break;
    }
    return 1;
}

//加輔助法術
int    RoleDataEx::AssistMagic( RoleDataEx* Target , int MagicID , int EffectTime )
{
	GameObjDbStructEx*  OrgDB = St_GetObjDB( MagicID );

	if( OrgDB == NULL )
		return -1;
	return AssistMagic( Target , OrgDB , EffectTime );
}

int    RoleDataEx::AssistMagic( RoleDataEx* Target , GameObjDbStructEx* OrgDB , int EffectTime )
{
    //assist( Target->BaseData.Buff.Size() <= 16 );
	NPCHateStruct* HateInfo;

    if( Target->BaseData.Buff.Size() > Target->BaseData.Buff.MaxSize() )
    {
        Target->BaseData.Buff.Clear();
    }

    int     i;
    //1 簡查是否有互斥的法術
    //  相同ID
    for( i = 0 ; i < Target->BaseData.Buff.Size() ; i++ )
    {
        BuffBaseStruct&  Buf = Target->BaseData.Buff[ i ];

        GameObjDbStructEx*  MagBuf = St_GetObjDB( Buf.BuffID );

		if( MagBuf->GUID == OrgDB->GUID )
		{
			//如果可不可互蓋
			if( OrgDB->MagicBase.EffectAddonType == 1  )
				break;
			//如果Client不用顯示Buf 的時間
			if( OrgDB->MagicBase.Setting.ShowBuffTime == false )
			{
				int DLV = Level() - Target->Level();
				Buf.Time = int( OrgDB->MagicBase.EffectTime - DLV * OrgDB->MagicBase.DLV_EffectTime );
				return Buf.Time;
			}

			Target->ClearBuffByPos( i );
			//如果 Buf 有暫時的仇恨值
			if( MagBuf->MagicBase.TempHateCost != 0 )
			{
				HateInfo = Target->GetHatePos( this->GUID() , this->DBID() );
				HateInfo->TempHatePoint -= MagBuf->MagicBase.TempHateCost;
			}

		}
        else if(     MagBuf->MagicBase.AssistType != EM_Magic_Type_NULL 
            &&  MagBuf->MagicBase.AssistType == OrgDB->MagicBase.AssistType )
        {
			//如果可不可互蓋
			if(		OrgDB->MagicBase.EffectAddonType == 1  
				&&	MagBuf->MagicBase.EffectLV == OrgDB->MagicBase.EffectLV)
				break;

            if( MagBuf->MagicBase.EffectLV > OrgDB->MagicBase.EffectLV )
				break;
            

			Target->ClearBuffByPos( i );
			//如果 Buf 有暫時的仇恨值
			if( MagBuf->MagicBase.TempHateCost != 0 )
			{
				HateInfo = Target->GetHatePos( this->GUID() , this->DBID() );
				HateInfo->TempHatePoint -= MagBuf->MagicBase.TempHateCost;
			}
            
            break;
        }
    }
    
    //2 buff是否滿了
    if( Target->BaseData.Buff.Size() >= Target->BaseData.Buff.MaxSize() )
    {
		BuffBaseStruct&  Buf = Target->BaseData.Buff[ 0 ];
		GameObjDbStructEx*  MagBuf = St_GetObjDB( Buf.BuffID );

		Target->ClearBuffByPos( 0 );

		//如果 Buf 有暫時的仇恨值
		if( MagBuf->MagicBase.TempHateCost != 0 )
		{
			HateInfo = Target->GetHatePos( this->GUID() , this->DBID() );
			HateInfo->TempHatePoint -= MagBuf->MagicBase.TempHateCost;
		}
    }

    //3 設定Buff資料
    int DLV = Level() - Target->Level();
    BuffBaseStruct  Buf;
    Buf.BuffID      = OrgDB->GUID;
	Buf.Power		= 1;
    Buf.OwnerID     = GUID();
	if( EffectTime == -1 )
	{
		Buf.Time = int( OrgDB->MagicBase.EffectTime - DLV * OrgDB->MagicBase.DLV_EffectTime );
	}
	else
	{
		Buf.Time = EffectTime;
	}

	//如果為 魔法盾
	Buf.Point = OrgDB->MagicBase.MagicShield.Point;

	Buf.Magic = OrgDB;
    Target->BaseData.Buff.Push_Back( Buf );
    Target->TempData.UpdateInfo.Recalculate = true;

	Target->CalTempHate( this , OrgDB->MagicBase.TempHateCost );

    return Buf.Time;
}

//清除所有Buff
void    RoleDataEx::ClearAllBuff()
{
	for( int i = 0 ; i < BaseData.Buff.Size() ; i++ )
	{
		Net_ClearAssistMagic( BaseData.Buff[i].BuffID );
	}

    BaseData.Buff.Clear();
    TempData.UpdateInfo.Recalculate = true;
	return ;
}

//清除Buff
bool    RoleDataEx::ClearBuff( int MagicID )
{
    for( int i = 0 ; i < BaseData.Buff.Size() ; i++ )
    {
        if( MagicID == BaseData.Buff[i].BuffID )
        {
			//Net_ClearAssistMagic( BaseData.Buff[i].BuffID );
            //BaseData.Buff.Erase( i );
			ClearBuffByPos( i );
            //TempData.UpdateInfo.Recalculate = true;
            return true;
        }
    }
    return false;
}

bool    RoleDataEx::ClearBuffByPos( int Pos )
{
    if( BaseData.Buff.Size() <= Pos )
        return false;


    Net_ClearAssistMagic( BaseData.Buff[Pos].BuffID );
    BaseData.Buff.Erase( Pos );
	
    TempData.UpdateInfo.Recalculate = true;
    return true;
}

//當打別人時 Buff 處理
void	RoleDataEx::OnAttackBuffProc( RoleDataEx* Target )
{
	if( Target->TempData.Attr.AssistMagicSetting.SpecialMagic == false )
		return;


	MagicProcInfo  MagicInfo;
	MagicInfo.Init();

	for( int i = 0 ; i < Target->BaseData.Buff.Size() ; i++ )
	{        
		int MagicID = Target->BaseData.Buff[i].Magic->MagicBase.OnAttackReboundMagicID;
		if(		Target->BaseData.Buff[i].Magic->MagicBase.Setting.SpecialMagic == false
			||	MagicID == 0 )
			continue;

		MagicProcInfo  MagicInfo;
		MagicInfo.State = EM_MAGIC_PROC_STATE_PERPARE;
		MagicInfo.TargetID			= this->GUID();			//目標
		MagicInfo.MagicCollectID	= MagicID;				//法術
		St_SpellMagic( Target ,  &MagicInfo );		
	}
}


//處理Buf的時效
void    RoleDataEx::BuffProc( )
{

    for( int i = 0 ; i < BaseData.Buff.Size() ; i++ )
    {        
		BaseData.Buff[i].Time --;
#ifdef _LOCAL_SERVER_
        if(     !BaseData.Buff[i].Magic->MagicBase.DotMagic.IsEmpty() 
            &&  BaseData.Buff[i].Time % BaseData.Buff[i].Magic->MagicBase.DotMagic.Time == 0 )
        {            
            RoleDataEx* Target = St_GetRoleData( BaseData.Buff[i].OwnerID );

			int Damage = BaseData.Buff[i].Magic->MagicBase.DotMagic.Base * -1;

			MagicShieldAbsorbProc( Target , BaseData.Buff[i].Magic , Damage );


            switch( BaseData.Buff[i].Magic->MagicBase.DotMagic.Type )
            {
            case 0:
                AddHP( Target , Damage * -1 );
                break;
            case 1:
                AddMP( Target , Damage * -1 );
                break;
            case 2:
                AddSP( Target , Damage * -1 );
                break;
            }
            
        }

		static vector<int> MagicList;
		MagicList.clear();

		if(     BaseData.Buff[i].Magic->MagicBase.OnTimeMagic_Magic != 0
			&&  BaseData.Buff[i].Time % BaseData.Buff[i].Magic->MagicBase.OnTimeMagic_Time == 0 )
		{
			MagicList.push_back( BaseData.Buff[i].Magic->MagicBase.OnTimeMagic_Magic );
			
			MagicProcInfo  MagicInfo;
			MagicInfo.Init();
			MagicInfo.State = EM_MAGIC_PROC_STATE_PERPARE;
			MagicInfo.TargetID			= this->GUID();				//目標
			MagicInfo.MagicCollectID	= BaseData.Buff[i].Magic->MagicBase.OnTimeMagic_Magic;			//法術
			St_SpellMagic( this ,  &MagicInfo );
			
		}

        if( BaseData.Buff[i].Time <= 0)
        {
			if( BaseData.Buff[i].Magic->MagicBase.OnTimeMagic_Magic != 0 )
			{
				MagicList.push_back( BaseData.Buff[i].Magic->MagicBase.OnTimeMagic_Magic );
			}          

			ClearBuffByPos( i );
			i--;
        }
		for( unsigned int i = 0 ; i < MagicList.size() ; i ++ )
		{
			MagicProcInfo  MagicInfo;
			MagicInfo.Init();
			MagicInfo.State = EM_MAGIC_PROC_STATE_PERPARE;
			MagicInfo.TargetID			= this->GUID();				//目標
			MagicInfo.MagicCollectID	= MagicList[ i ];			//法術
			St_SpellMagic( this ,  &MagicInfo );			
		}
#endif
    }

}

//設定武器狀態
void	RoleDataEx::FixWeaponType()
{/*
	GameObjectWeaponENUM& MainWeaponType = TempData.Attr.MainWeaponType;
	GameObjectWeaponENUM& SecWeaponType  = TempData.Attr.SecWeaponType;

	if( MainWeaponType ==  EM_Weapon_Unarmed )
	{
		if( SecWeaponType ==  EM_Weapon_None && BaseData.EQ.SecondHand.IsEmpty() )
		{
			SecWeaponType = EM_Weapon_Unarmed;
		}
	}
	*/
}

//取得對某魔法進行抗性運算結果( + 加血 - 扣血 )
float		RoleDataEx::CalResistDMG( MagicResistENUM  MagicType , float Damage )
{
	if( Damage >= 0 )
		return Damage;

	switch( MagicType )
	{
	case EM_MagicResist_Earth:   
	case EM_MagicResist_Water:   
	case EM_MagicResist_Fire:    
	case EM_MagicResist_Wind:    
	case EM_MagicResist_Light:   
	case EM_MagicResist_Darkness:
		break;
	default:
		return Damage;
	}

	int ResistValue = int( TempData.Attr.Fin.Resist._ArrList[ MagicType ] );

	ResistArgType_ENUM	ResistType = TempData.Attr.GetResistType( ResistValue );

	switch( ResistType )
	{
	case EM_ResistArgType_Power0:
		return 0;

	case EM_ResistArgType_Power25:	
		return Damage/4+1;

	case EM_ResistArgType_Power50:	
		return Damage/2+1;

	case EM_ResistArgType_Power75:	
		return Damage*3/4+1;

	case EM_ResistArgType_Power100:	
		return Damage;
	}

	return 0;
}