#include "RoleDataEx.h"
#include  <math.h>
#include "BaseFunction/BaseFunction.h"

/*
int RoleDataEx::SelfClock( )
{
    return G_Clock - ItemID();
}
*/

void RoleDataEx::IncDMove( )
{
    if( TempData.Move.ProcDelay == 0 )
        return;


    if( TempData.Move.AddeDelay > 0 )
    {
        TempData.Move.AddeDelay --;
        return;
    }

    TempData.Move.ProcDelay-- ;
    
    if( TempData.Move.ProcDelay <= 0 )
    {
        BaseData.Pos.X = TempData.Move.Tx;
        BaseData.Pos.Y = TempData.Move.Ty;
        BaseData.Pos.Z = TempData.Move.Tz;
    }
    else
    {
        BaseData.Pos.X += TempData.Move.Dx;
        BaseData.Pos.Y += TempData.Move.Dy;
        BaseData.Pos.Z += TempData.Move.Dz;
    }    
}
//------------------------------------------------------------------------------------
void    RoleDataEx::DelMagicCost( GameObjDbStructEx* MagicDB )
{
	MagicSpellCostTypeENUM CostType	= MagicDB->MagicCol.Cost.Type ;
	int CostValue	= MagicDB->MagicCol.Cost.Value;

	switch( CostType )
	{
	case EM_MagicSpellCostType_None:					//無消耗

		break;
	case EM_MagicSpellCostType_HP:						//消耗 HP
		{
			 AddHP( this , CostValue*-1 );
		}
		break;
	case EM_MagicSpellCostType_MP:						//消耗 MP
		{
			CostValue =  int( CostValue * ( 100 - TempData.Attr.Fin.ManaDecrease )/100 );   
			 AddMP( this , CostValue*-1 );
		}
		break;
	case EM_MagicSpellCostType_SP_Warrior:			//消耗 SP 戰士	
		{
			if( BaseData.Voc == EM_Vocation_Warrior )
			{
				AddSP( this , CostValue*-1 );
			}
			else if( BaseData.Voc_Sub == EM_Vocation_Warrior )
			{
				AddSP_Sub( this , CostValue*-1 );
			}
		}break;
	case EM_MagicSpellCostType_SP_Ranger:			//消耗 SP 遊俠
		{
			if( BaseData.Voc == EM_Vocation_Ranger )
			{
				AddSP( this , CostValue*-1 );
			}
			else if( BaseData.Voc_Sub == EM_Vocation_Ranger )
			{
				AddSP_Sub( this , CostValue*-1 );
			}
		}break;
	case EM_MagicSpellCostType_SP_Rogue:			//消耗 SP 盜賊	
		{
			if( BaseData.Voc == EM_Vocation_Rogue )
			{
				AddSP( this , CostValue*-1 );
			}
			else if( BaseData.Voc_Sub == EM_Vocation_Rogue )
			{
				AddSP_Sub( this , CostValue*-1 );
			}
		}break;
		/*
	case EM_MagicSpellCostType_SP:						//消耗 SP
		{
			AddSP( this , CostValue*-1 );
		}
		break;*/
	case EM_MagicSpellCostType_Item:					//消耗 物品
		{
			DelBodyItem( CostValue , 1 );
		}
		break;
	case EM_MagicSpellCostType_Ammo_Gun:				//消耗 子彈
	case EM_MagicSpellCostType_Ammo_Bow:				//消耗 弓箭矢
	case EM_MagicSpellCostType_Ammo_CossBow:			//消耗 十字弓箭矢
	case EM_MagicSpellCostType_Ammo_Throw:				//消耗 投擲物
		{
			ItemFieldStruct* Item = GetEqItem( EM_EQWearPos_Ammo );	
			Item->Count --;
			if( Item->Count <= 0 )
				Item->Init();
			Net_FixItemInfo_EQ( EM_EQWearPos_Ammo );
		}
		break;

	}

}
//------------------------------------------------------------------------------------
//計算到某一點的直線所需時間
int		RoleDataEx::MoveTime( float X , float Y , float Z )
{
    int Ret = int( ( Length( X ,  Y ,  Z ) * 10 )   /  MoveSpeed() + 0.5 )  ;

    if( Ret <= 0 )
        return 1;
    return Ret;
}
//------------------------------------------------------------------------------------
//取得SampleRoleData
void    RoleDataEx::GetSampleRoleData( SampleRoleData* Data )
{
    Data->Level      = BaseData.AbilityList[ BaseData.Voc ].Level;
    Data->OrgObjID   = BaseData.ItemInfo.OrgObjID;
    Data->Race       = BaseData.Race;
    Data->Voc        = BaseData.Voc;
//    strncpy( Data->RoleName , BaseData.RoleName , sizeof(Data->RoleName) );
    Data->RoleName  = BaseData.RoleName;
    Data->Sex        = BaseData.Sex;
//    strncpy( Data->ZoneName , "Unknow" , sizeof(Data->ZoneName) );

}
//------------------------------------------------------------------------------------
//取得NPCData的資料
void    RoleDataEx::GetNPCData( NPCData* Data )
{
    Data->DBID = Base.DBID;

    Data->OrgObjID  = BaseData.ItemInfo.OrgObjID;							        
//    memcpy( Data->CreateTime , Base.CreateTime , sizeof( Data->CreateTime ) );
    Data->CreateTime = Base.CreateTime;
    Data->Mode      = BaseData.Mode;
//    memcpy( Data->RoleName , BaseData.RoleName , sizeof( Data->RoleName ) );	    
    Data->RoleName  = BaseData.RoleName;
    Data->ZoneID    = BaseData.ZoneID;	
    Data->Pos       = BaseData.Pos;
    Data->LiveTime  = SelfData.LiveTime;
    Data->OwnerDBID = SelfData.OwnerDBID;
    Data->PID       = SelfData.PID;
//    memcpy( Data->PlotClassName , SelfData.PlotClassName , sizeof( Data->PlotClassName ) );
//    memcpy( Data->AutoPlot , SelfData.AutoPlot , sizeof( Data->AutoPlot ) );
    Data->PlotClassName = SelfData.PlotClassName;
    Data->AutoPlot = SelfData.AutoPlot;
	Data->QuestID	= SelfData.NpcQuestID;
    Data->CreateAccount = TempData.CreateAccount;
}
//------------------------------------------------------------------------------------
//取各個物件的時脈於數
bool    RoleDataEx::ClockMod( int Mod )
{
    return ( ( G_Clock - TempData.Sys.ItemID ) % Mod == 0 );
}
//-----------------------------------------------------------------------------------------------
//攻擊距離
int	RoleDataEx::MainAttackRange( RoleData* Target )
{
    return int( TempData.BoundRadius + Target->TempData.BoundRadius + TempData.Attr.MainAttackRange );	

}
int	RoleDataEx::SecAttackRange( RoleData* Target )
{
	return int( TempData.BoundRadius + Target->TempData.BoundRadius + TempData.Attr.SecAttackRange );	

}
//-----------------------------------------------------------------------------------------------
//與看的方向所夾的角度
float   RoleDataEx::CalAngle( RoleDataEx* Target )
{
    double Dir; /*
    if( BaseData.Pos.Dir < 180 )
        Dir = BaseData.Pos.Dir / 57.2958;
    else
        Dir = ( 360 -BaseData.Pos.Dir )/57.2958;*/
    Dir = ( 360 -BaseData.Pos.Dir )/57.2958;

    double x = cos( Dir );
    double z = sin( Dir );

    double x1 = Target->BaseData.Pos.X - BaseData.Pos.X;
    double z1 = Target->BaseData.Pos.Z - BaseData.Pos.Z;

    double Len = sqrt( x1*x1 + z1*z1 );

    if( Len < 0.1 )
        return 0;

    x1 /= Len;
    z1 /= Len;

    double RetDir = acos( x*x1 + z*z1 ) * 57.295;

    return (float)RetDir;

}
//-----------------------------------------------------------------------------------------------
//計算面對的方向
float		RoleDataEx::CalDir( float dx , float dz )
{

    if( FloatEQU( dz , 0 ) )
        dz = float( 0.01 );

    if( FloatEQU( dx , 0 ) )
        dx = float( 0.01 );

    double	L	= sqrt( dx * dx + dz * dz );
//    if( L < 0.001 )
//        return 0;
    
    double	Dir = acos( dx / L ) * 57.2958;

    if( Dir < 0.001 )
        Dir = 0.001;

    if( dz > 0 )
        Dir = 360 - Dir;
    
/*    if( dz < 0 )
        Dir = fmod( 360 - Dir , 360 );
    else
        Dir = fmod( Dir	, 360 );
*/
    return (float)Dir;
}
//-----------------------------------------------------------------------------------------------
float	RoleDataEx::CalDir( RoleDataEx* Target )
{
    return CalDir(	float( Target->BaseData.Pos.X - BaseData.Pos.X )  
        ,	float( Target->BaseData.Pos.Z - BaseData.Pos.Z )	);
}
//-----------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
//攻擊目標
bool	RoleDataEx::AttackTarget( int TargetID )
{
    RoleDataEx*	TargetVal = (RoleDataEx*)St_GetRoleData( TargetID );

    if( TargetVal == NULL )
        return false;

    //如果為玩家
    if( IsPlayer() )
    {
        SetAttack( TargetVal );
        return true;
    }
    else if ( IsNPC() )
    {
        if (CheckStrikback())
        {
            SetAttack( TargetVal );
            //if( SetAttack( TargetVal ) == true )
            //    SetFollow( TargetVal );
        }
        return true;
    }

    return false;
}
//------------------------------------------------------------------------------------
//停止攻擊
bool	RoleDataEx::StopAttack( )
{
    return SetAtkFolOff();
}
//------------------------------------------------------------------------------------
//清除使用中的物品( 使用失敗清除 )
bool    RoleDataEx::ClsUseItem( )
{
    int Pos = TempData.Magic.UseItemPos;
    int Type = TempData.Magic.UseItemType;
    //取得欄位資料

    ItemFieldStruct* Item = GetItem( Pos , Type  );
    if( Item == NULL || Item->Pos != EM_USE_ITEM )
        return false;

    Item->Pos = EM_ItemState_NONE;

    //資料修正
    Net_FixItemInfo( Pos , Type );

    TempData.Magic.ClsUseItem();
    return true;
}
//------------------------------------------------------------------------------------
//刪除使用物品
bool    RoleDataEx::DelUseItem( )
{
    if( TempData.Magic.UseItem == 0 )
        return true;

    int Pos = TempData.Magic.UseItemPos;
    int Type = TempData.Magic.UseItemType;

    //取得欄位資料
    ItemFieldStruct* Item = GetItem( Pos , Type );
    if( Item == NULL || Item->Pos != EM_USE_ITEM )
        return false;

    //檢查是否消耗
    GameObjDbStructEx	*OrgDB;
    OrgDB = St_GetObjDB( Item->OrgObjID );

    if( OrgDB == NULL || OrgDB->Classification != EM_ObjectClass_Item)
        return false;


    //清除欄位資料
    if( OrgDB->Mode.Expense == true )
    {
        if( Item->Count <= 1 )
            Item->Init();
        else
            Item->Count --;

    }

    Item->Pos = EM_ItemState_NONE;

    //資料修正
    Net_FixItemInfo( Pos , Type );


    TempData.Magic.ClsUseItem();

    return true;
}
//------------------------------------------------------------------------------------
void    RoleDataEx::StopMove( )
{
    BaseData.Pos.X = TempData.Move.Tx;
    BaseData.Pos.Y = TempData.Move.Ty;
    BaseData.Pos.Z = TempData.Move.Tz;
    TempData.Move.ProcDelay = 0;
    TempData.Move.AddeDelay = 0;


//    TempData.AI.MoveAiType = EM_NPC_MOVETYPE_NORMAL;
}
//------------------------------------------------------------------------------------
void    RoleDataEx::StopMoveNow( )
{
	TempData.Move.Tx = BaseData.Pos.X;
	TempData.Move.Ty = BaseData.Pos.Y;
	TempData.Move.Tz = BaseData.Pos.Z;
	TempData.Move.ProcDelay = 0;
	TempData.Move.AddeDelay = 0;


//	TempData.AI.MoveAiType = EM_NPC_MOVETYPE_NORMAL;
}
//------------------------------------------------------------------------------------
//重設擁有的被動技能
void    RoleDataEx::ReSetPassiveSkill( )
{
    TempData.PassiveSkill.Clear();
    GameObjDbStructEx	*MagicCol;
	GameObjDbStructEx	*MagicBase;
	
    for( int i = 0 ; i < _MAX_NormalSkill_COUNT_+_MAX_NormalSkill_COUNT_+ _MAX_SPSkill_COUNT_; i++ )
    {
        int SkillID = TempData.Skill.AllSkill[ i ];

        MagicCol = St_GetObjDB( SkillID );
        if( MagicCol->IsMagicCollect() == false )
            continue;

        if( MagicCol->MagicCol.EffectType != EM_Magic_Eq )
            continue;

		for( int i = 0 ; i < _MAX_MAGICCOLLECT_COUNT_ ; i++ )
		{
			MagicBase = static_cast<GameObjDbStructEx*>( MagicCol->MagicCol.Magic[i].MagicBaseDB );
			if( MagicBase == NULL || MagicBase->IsMagicBase() == false )
				continue;

			TempData.PassiveSkill.Push_Back( MagicBase->GUID );
		}
    }
}
//------------------------------------------------------------------------------------
//初始化主副職法術資料
bool    RoleDataEx::InitMagicBook( )
{   

    GameObjDbStructEx	*MainJobMB;
    GameObjDbStructEx	*SubJobMB;
    GameObjDbStructEx	*BaseMagic;
	GameObjDbStructEx	*KeyItemDB;
    MainJobMB = St_GetObjDB( Def_ObjectClass_LearnMagic + BaseData.Voc );    
    SubJobMB  = St_GetObjDB( Def_ObjectClass_LearnMagic + BaseData.Voc_Sub );    

    if( MainJobMB == NULL )
    {        
        return false;
    }
    //主職    
    //設定一般法術
    for( int i = 0 ; i < _MAX_NormalSkill_COUNT_ ; i++ )
    {
        TempData.Skill.MainJob[ i ] = MainJobMB->LearnMagic.NormalSkill[ i ].MagicID;

		BaseMagic = St_GetObjDB( TempData.Skill.MainJob[ i ] );
		if( BaseMagic == NULL )
		{
			continue;
		}

		int DLV = TempData.Attr.Level - MainJobMB->LearnMagic.NormalSkill[ i ].LearnLV;
		if( DLV < 0 )
		{
			TempData.Skill.MainJob[ i ]	= 0;
			continue;
		}
		KeyItemDB = St_GetObjDB( MainJobMB->LearnMagic.NormalSkill[ i ].KeyItemID );

		if( KeyItemDB->IsKeyItem() == false )
			continue;

		if( BaseData.KeyItem.GetFlag( KeyItemDB->GUID - Def_ObjectClass_KeyItem) == false )
		{
			TempData.Skill.MainJob[ i ]	= 0;
		}
    }

    //設定職業法術
    for( int i = 0 ; i < _MAX_SPSkill_COUNT_ ; i++ )
    {
        TempData.Skill.SP[ i ] = MainJobMB->LearnMagic.SPSkill[ i ].MagicID;

		BaseMagic = St_GetObjDB( TempData.Skill.SP[ i ] );
		if( BaseMagic == NULL )
		{
			continue;
		}

		int DLV = TempData.Attr.Level - MainJobMB->LearnMagic.SPSkill[ i ].LearnLV;
		if( DLV < 0 )
		{
			TempData.Skill.SP[ i ]	= 0;
			continue;
		}
		KeyItemDB = St_GetObjDB( MainJobMB->LearnMagic.SPSkill[ i ].KeyItemID );

		if( KeyItemDB->IsKeyItem() == false )
			continue;

		if( BaseData.KeyItem.GetFlag( KeyItemDB->GUID - Def_ObjectClass_KeyItem) == false )
		{
			TempData.Skill.SP[ i ]	= 0;
		}
    }

    //設定副職
    if( SubJobMB != NULL )
    {
        for( int i = 0 ; i < _MAX_NormalSkill_COUNT_ ; i++ )
        {
            TempData.Skill.SubJob[ i ] = SubJobMB->LearnMagic.NormalSkill[ i ].MagicID;

            BaseMagic = St_GetObjDB( TempData.Skill.SubJob[ i ] );
            if( BaseMagic == NULL )
            {
                continue;
            }

            int DLV = TempData.Attr.Level_Sub - SubJobMB->LearnMagic.NormalSkill[ i ].LearnLV;
            if( DLV < 0 )
            {
				TempData.Skill.SubJob[ i ]	= 0;
				continue;
            }
			KeyItemDB = St_GetObjDB( SubJobMB->LearnMagic.NormalSkill[ i ].KeyItemID );

			if( KeyItemDB->IsKeyItem() == false )
				continue;

			if( BaseData.KeyItem.GetFlag( KeyItemDB->GUID - Def_ObjectClass_KeyItem) == false )
			{
				TempData.Skill.SubJob[ i ]	= 0;
			}

        }
    }

    return true;
}
//------------------------------------------------------------------------------------
//檢察是否可以法術配點
bool    RoleDataEx::CheckSetMagicPoint( int MagicPos )
{
//    if( MagicPos >=  _MAX_NormalSkill_COUNT_ )
//        return false;
/*
    //SkillBaseStruct* Skill = BaseData.Skill.MainJob[ MagicPos ];
    SkillBaseStruct* Skill = BaseData.Skill.GetSkill_MainJob( MagicPos );
    if( Skill == NULL )
        return false;

    GameObjDbStructEx	*MainJobMB = St_GetObjDB( Def_ObjectClass_LearnMagic + BaseData.Voc );    
    GameObjDbStructEx	*BaseMagic = St_GetObjDB( Skill->SkillID );

    if( BaseMagic == NULL || MainJobMB == NULL )
        return false;

    JobNormalSkillBase&     Book  = MainJobMB->LearnMagic.NormalSkill[ MagicPos ];

    int DLV = Level() - Book.BaseLearnLV;
    int MaxLV;

    //等級不足
    if( DLV < 0 )
        return false;

    if( Book.Learn_DLV == 0 )
    {
        MaxLV = Book.MaxLV;
    }
    else
    {
        MaxLV = DLV / Book.Learn_DLV + 1;
    }

    if( MaxLV > Book.MaxLV )
        MaxLV = Book.MaxLV;

    if( Skill->Point != 0 )
    {
        if( Skill->Point >= MaxLV )
            return false;
    }
    //檢查法術配點是否足夠
    //if( TempData.Attr.Ability->SkillPoint < BaseMagic->AllMagic[ Skill->Point ]->Magic.CostPoint )
	if( TempData.Attr.Ability->SkillPoint < 1 )
        return false;

    //資料有問題
//    if( BaseMagic->AllMagic[ Skill->Point  ]->Magic.CostPoint < 0 )
//        return false;

    //1檢查是否有重要物品
    if( Book.KeyItemID != 0 )
    {
        if( BaseData.KeyItem.GetFlag( Book.KeyItemID - Def_ObjectClass_KeyItem ) == false )
            return false;
    }

    //2檢查需求法術
    for( int i = 0 ; i < 2 ; i++ )
    {
        GameObjDbStructEx	*NeedMagic = St_GetObjDB( Book.RequestMagicID[ i ] );
        int     MagicBase;
        int     MagicLV;
        bool    IsFind;
        if( NeedMagic == NULL )
            continue;

        if( NeedMagic->MagicCol.MagicBase != 0 )
        {
            MagicBase = NeedMagic->MagicCol.MagicBase;
            MagicLV   = NeedMagic->MagicCol.MagicLV;
        }
        else
        {
            MagicBase = NeedMagic->GUID;
            MagicLV   = 1;

        }

        IsFind = false;
        for( int j = 0 ; j < _MAX_NormalSkill_COUNT_ ; j++ )
        {
            if(     BaseData.Skill.MainJob[ j ].SkillID == MagicBase 
                &&  BaseData.Skill.MainJob[ j ].Point  >= MagicLV )
            {
                IsFind = true;
                break;
            }
        }

        if( IsFind == false )
            return false;
    }
*/
    return true;
}
//------------------------------------------------------------------------------------
//重設職業資料
void    RoleDataEx::ResetJobSkill( )
{/*
    GameObjDbStructEx	*MainJobMB = St_GetObjDB( Def_ObjectClass_LearnMagic + BaseData.Voc );    
    if( MainJobMB == NULL )
        return;

    for( int i = 0 ; i < _MAX_SPSkill_COUNT_ ; i++ )
    {
        TempData.Skill.SP[i].Point = 0;

        GameObjDbStructEx	*SkillDB =  St_GetObjDB( TempData.Skill.SP[i] );    
        if( SkillDB == NULL )
            continue;

//        if( BaseData.Skill.SP[i].Point != 0 )
//            continue;
        
        //檢查是否有 KeyItem
        int KeyItem = MainJobMB->LearnMagic.SPSkill[i].KeyItemID;
        int LearnLV   = MainJobMB->LearnMagic.SPSkill[i].LearnLV;

        if( LearnLV > Level() )
            continue;

        if( KeyItem != 0 )
        {
            if( BaseData.KeyItem.GetFlag( KeyItem - Def_ObjectClass_KeyItem ) == false )
            {
                continue;
            }
        }
        
        //TempData.Skill.SP[i].Point = 1;
        //SetValue( (RoleValueName_ENUM)( EM_RoleValue_SPMagic + i )  , 1 );
    
    }
*/
}
//------------------------------------------------------------------------------------
//檢查是否法術與位置資料與角色點術相符合
bool    RoleDataEx::CheckRoleMagic( int MagicID , int MagicPos )
{
	if( (unsigned)MagicPos >= _MAX_SPSkill_COUNT_+_MAX_NormalSkill_COUNT_+_MAX_NormalSkill_COUNT_  )
		return false;

	if( TempData.Skill.AllSkill[ MagicPos ] != MagicID )
		return false;

    return true;
}
//------------------------------------------------------------------------------------
/*
//檢查是否法術與位置資料與角色點術相符合
bool    RoleDataEx::CheckRoleSPMagic( int MagicID , int MagicPos )
{
    if( MagicID != BaseData.Skill.SP[ MagicPos ].SkillID )
        return false;
    return true;
}
*/

//取得物件源始的主人
RoleDataEx* RoleDataEx::GetOrgOwner( )
{
    RoleDataEx* Owner = this;
    while( 1 )
    {
        if( Owner->OwnerGUID() == -1 )
            break;

        RoleDataEx* Temp = St_GetRoleData( Owner->OwnerGUID() );
        if( Temp == NULL )
            break;
        Owner = Temp;
    }
    return Owner;
}
//------------------------------------------------------------------------------------
//收尋愁恨的角色
RoleDataEx*    RoleDataEx::SearchHate( )
{
    RoleDataEx* HateRole;
    RoleDataEx* MaxHateRole = NULL;
    float         MaxHatePoint = 0;
    float         TempHatePoint;
    for( int i = 0 ; i < TempData.NPCHate.Hate.Size() ;  i++ )
    {		
        HateRole = St_GetRoleData( TempData.NPCHate.Hate[ i ].ItemID );
        if( HateRole == NULL || HateRole->IsDead() )
        {
            TempData.NPCHate.Hate.Erase( i );
            i--;
            continue;
        }

		if( HateRole->GUID() == TargetID() )
			continue;

		PathProcStruct& Move = TempData.Move;

		if(     ( HateRole->X() - Move.RetX  )*( HateRole->X() - Move.RetX  )
//			+	( HateRole->Y() - Move.RetY  )*( HateRole->Y() - Move.RetY  )
			+	( HateRole->Z() - Move.RetZ  )*( HateRole->Z() - Move.RetZ  )        > 300*300 )
			continue;

		if(CheckAttackable( HateRole ) == false || CheckPhyAttack( HateRole) == false )
		{
			continue;
		}

		float Len = Length( HateRole );
		if( Len >= 200 )
			continue;

        TempHatePoint = TempData.NPCHate.Hate[ i ].TotalHatePoint() / float( Len + 20 ) ;
        if( MaxHateRole == NULL || MaxHatePoint < TempHatePoint  )
        {
            MaxHateRole = HateRole;
            MaxHatePoint = TempHatePoint;
        }        
    }
    return MaxHateRole;
}
//------------------------------------------------------------------------------------
//搜尋新的目標 找不到就停止攻擊
bool		RoleDataEx::FindNewHateTarget( )
{
	if( !IsNPC() )
		return false;

	if( IsAttack() == false )
		return false;

	RoleDataEx* Target = SearchHate( );
	if( Target == NULL )
	{
		SetAtkFolOff( );
		return false;
	}
	SetAttack( Target );

	return true;
}

//取得ＨＱ品的額外增加機率
int		RoleDataEx::GetHQExtraValue( SkillValueTypeENUM SkillType )
{
	switch( SkillType )
	{
	case EM_SkillValueType_BlackSmith:	
		return int(TempData.Attr.Fin.SkillValue.BlackSmith);
	case EM_SkillValueType_Carpenter:	
		return int(TempData.Attr.Fin.SkillValue.Carpenter);
	case EM_SkillValueType_MakeArmor:
		return int(TempData.Attr.Fin.SkillValue.MakeArmor);
	case EM_SkillValueType_Tailor:
		return int(TempData.Attr.Fin.SkillValue.Tailor);
	case EM_SkillValueType_Cook:
		return int(TempData.Attr.Fin.SkillValue.Cook);
	case EM_SkillValueType_Alchemy:
		return int(TempData.Attr.Fin.SkillValue.Alchemy);
	}
	return 0;
}

//-------------------------------------------------------------------------------------------
//下線有計算的Buff or Coldown處理
void	RoleDataEx::ProcOffLineTime()
{
	//__time32_t格式
	int		OffLineTime = RoleDataEx::G_Now - Base.LogoutTime;
	if( OffLineTime < 0 )
		OffLineTime = 0;

	//StaticVector< RefineBuffStruct , _MAX_REFINE_BUFF_COUNT_ > RefineColdown; //合成Buff

	//法術Coldown處理
	BaseData.Coldown.NeedUpdatePos.Clear();
	for( int i = 0 ; i < DEF_MAX_COLDOWN_COUNT_ALL ; i++ )
	{
		if( BaseData.Coldown.All[i] <= OffLineTime )
		{
			BaseData.Coldown.All[i] = 0;
		}
		else
		{
			BaseData.Coldown.All[i] -= OffLineTime;
			BaseData.Coldown.NeedUpdatePos.Push_Back( i );
		}
	}
	
	//合成Buff
	for( int i = 0 ; i < BaseData.RefineColdown.Size() ; i++ )
	{
		if( BaseData.RefineColdown[i].Coldown <= OffLineTime )
		{
			BaseData.RefineColdown[i].Coldown = 0;
			BaseData.RefineColdown[i].RecipeID = 0;
			BaseData.RefineColdown.Erase( i );
			i--;
		}
		else
		{
			BaseData.RefineColdown[i].Coldown -= OffLineTime;

		}

	}

}

//取得 OnlinePlayerInfoStruct 的資料
void	RoleDataEx::GetOnlinePlayerInfo( OnlinePlayerInfoStruct& Info )
{
	Info.DBID	 = DBID();
	Info.GUID	 = GUID();
	Info.Name	 = RoleName();
	Info.ZoneID  = ZoneID();
	Info.Account = Base.Account_ID;
	Info.Voc	 = BaseData.Voc;
	Info.Voc_Sub = BaseData.Voc_Sub;
	Info.Sex	 = BaseData.Sex;
	Info.Look	 = BaseData.Look;
	Info.LV		 = TempData.Attr.Level;
	Info.LV_Sub  = TempData.Attr.Level_Sub;
	Info.ProxyID = TempData.Sys.ProxyID;
	Info.SockID  = TempData.Sys.SockID;
}

//魔法盾吸收計算 回傳吸收多少
int RoleDataEx::MagicShieldAbsorbProc( RoleDataEx* AttackRole , GameObjDbStruct* AtkMagic , int &Damage )
{
	if( Damage < 0 )
		return 0;

	if( AttackRole == NULL )
		AttackRole = this;

	int AbsorbDamage = 0;
	int TotalAbsorbDamage = 0;

	if(	TempData.Attr.AssistMagicSetting.MagicShield == false )
		return 0;

	for( int i = 0 ; i < BaseData.Buff.Size() ; i++ )
	{   
		BuffBaseStruct& Buff = BaseData.Buff[i];
		GameObjectMagicStruct* MagicBase = &(Buff.Magic->MagicBase);

		if( MagicBase->Setting.MagicShield == false )
			continue;

		if(		AtkMagic == NULL 
			||	AtkMagic->MagicBase.EffectType == EM_Magic_Phy )
		{
			if(		MagicBase->MagicShield.Effect != EM_MagicShieldEffec_All 
				&&	MagicBase->MagicShield.Effect != EM_MagicShieldEffec_Phy )
				continue;
		}
		else if( AtkMagic->MagicBase.EffectType == EM_Magic_Magic )
		{
			switch( MagicBase->MagicShield.Effect )
			{
			case EM_MagicShieldEffec_All:			//所有攻擊
				break;
			case EM_MagicShieldEffec_Phy:			//物理攻擊
				continue;
			case EM_MagicShieldEffec_Magic:			//法術攻擊
				break;
			case EM_MagicShieldEffec_Earth:			//地系法術攻擊
				if( MagicBase->MagicType != EM_MagicResist_Earth )
					continue;
				break;
			case EM_MagicShieldEffec_Water:    		//水系法術攻擊
				if( MagicBase->MagicType != EM_MagicResist_Water )
					continue;
				break;
			case EM_MagicShieldEffec_Fire:     		//火系法術攻擊
				if( MagicBase->MagicType != EM_MagicResist_Fire )
					continue;
				break;
			case EM_MagicShieldEffec_Wind:     		//風系法術攻擊
				if( MagicBase->MagicType != EM_MagicResist_Wind )
					continue;
				break;
			case EM_MagicShieldEffec_Light:    		//光系法術攻擊
				if( MagicBase->MagicType != EM_MagicResist_Light )
					continue;
				break;
			case EM_MagicShieldEffec_Darkness: 		//暗系法術攻擊
				if( MagicBase->MagicType != EM_MagicResist_Darkness )
					continue;
				break;
			}
		}		
		else
			continue;

		switch( MagicBase->MagicShield.Type )
		{
		case EM_MagicShieldType_MP:			//MP抵消HP
			if( Damage < BaseData.MP )
			{
				AddMP( AttackRole , Damage * -1 );
				AbsorbDamage = Damage;
				Damage = 0;
			}
			else
			{
				AbsorbDamage = BaseData.MP;
				Damage = Damage - BaseData.MP;
				AddMP( AttackRole , AbsorbDamage * -1 );
				Buff.Time = 0;
			}				
			break;
		case EM_MagicShieldType_Times:		//抵消次數
			{
				if( Buff.Point <= 0 )
				{
					Buff.Time = 0;
					break;
				}

				Buff.Point--;
				if( Buff.Point == 0 )
					Buff.Time = 0;

				AbsorbDamage = Damage;
				Damage = 0;				
			}
			break;
		case EM_MagicShieldType_Point:		//抵消法數設定的點數

			if( Damage < Buff.Point )
			{
				Buff.Point -= Damage;
				AbsorbDamage = Damage;
				Damage = 0;
			}
			else
			{
				AbsorbDamage = Buff.Point;
				Damage = Damage - Buff.Point;
				Buff.Time = 0;
				Buff.Point = 0;
			}	

			break;
		}
		if( AbsorbDamage != 0 )
		{
			int AtkMagicGUID = 0;
			if( AtkMagic != NULL )
				AtkMagicGUID = AtkMagic->GUID;

			Net_MagicShieldInfoRange( AttackRole->GUID() , GUID() , AtkMagicGUID , Buff.BuffID , AbsorbDamage );
			TotalAbsorbDamage += AbsorbDamage;
		}

		if( Damage == 0 )
			break;
	}
	return  TotalAbsorbDamage;
}