#include "RoleDataEx.h"
//-----------------------------------------------------------------------------------------
void    RoleDataEx::ChangeZoneInit( )
{
    TempData.Sys.SecRoomID = -1;
    TempData.Sys.SecX = -1;
    TempData.Sys.SecZ = -1;
	TempData.Sys.LoginProtect = 0;
    TempData.Sys.ChangeZoneTime = 4000 + RoleDataEx::G_SysTime;
	TempData.Sys.MirrorCount = 0;
	memset( &TempData.AI , 0 , sizeof(TempData.AI) );
//	TempData.Sys.SockID = -1;
    BaseData.Mode.Fight = true;

	TempData.Attr.Ability = &BaseData.AbilityList[ BaseData.Voc ];
    
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::LiveTime( int value )
{
    if( value != -1 )
        value = G_SysTime + value;

    SelfData.LiveTime = value ;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::LiveTime( )
{
    if( SelfData.LiveTime == -1 )
        return 0xffffff;

    return SelfData.LiveTime - G_SysTime;
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::WorldGUID( int value )
{
    TempData.Sys.WorldGUID = value;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::WorldGUID( )
{
    return TempData.Sys.WorldGUID;
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::OwnerGUID( int ID )
{
    TempData.Sys.OwnerGUID = ID;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::OwnerGUID( )
{
    return TempData.Sys.OwnerGUID;
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::OwnerDBID( int ID )
{
    SelfData.OwnerDBID = ID;
}
int     RoleDataEx::OwnerDBID( )
{
    return SelfData.OwnerDBID;
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::GUID( int value )
{
    TempData.Sys.GUID = value;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::GUID( )
{
    return TempData.Sys.GUID;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::ItemID( )
{
    return TempData.Sys.ItemID;
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::SockID( int value )
{
    TempData.Sys.SockID = value;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::SockID( )
{
    return TempData.Sys.SockID;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::ZoneID( )
{
    return BaseData.ZoneID;
}
void    RoleDataEx::ZoneID( int ZoneID )
{
    BaseData.ZoneID = ZoneID;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::RoomID( )
{
    return BaseData.RoomID;
}
//-----------------------------------------------------------------------------------------
void     RoleDataEx::RoomID( int value )
{
    BaseData.RoomID = value;
}
//-----------------------------------------------------------------------------------------
RolePosStruct*  RoleDataEx::Pos( )
{
    return &BaseData.Pos;
}
//-----------------------------------------------------------------------------------------
float   RoleDataEx::X( )
{
    return BaseData.Pos.X;
}
//-----------------------------------------------------------------------------------------
float   RoleDataEx::Y( )
{
    return BaseData.Pos.Y;
}
//-----------------------------------------------------------------------------------------
float   RoleDataEx::Z( )
{
    return BaseData.Pos.Z;
}
//-----------------------------------------------------------------------------------------
float   RoleDataEx::Dir( )
{
    return BaseData.Pos.Dir;
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::Pos( float X , float Y , float Z , float Dir )
{
    BaseData.Pos.X = X;
    BaseData.Pos.Y = Y;
    BaseData.Pos.Z = Z;
    BaseData.Pos.Dir = Dir;

    TempData.Move.Tx = X;
    TempData.Move.Ty = Y;
    TempData.Move.Tz = Z;

    TempData.Move.ProcDelay = 0;
    TempData.Move.AddeDelay = 0;
}
//-----------------------------------------------------------------------------------------
const char*   RoleDataEx::Account_ID( )
{
    return Base.Account_ID.Begin();
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::Account_ID( char* Name )
{
//    strncpy( Base.Account_ID , Name , sizeof( Base.Account_ID ) );
    Base.Account_ID = Name;
}
//-----------------------------------------------------------------------------------------
//取出險象所需資料
void    RoleDataEx::PlayerGraph( PlayerGraphStruct& GraphObj )
{
    GraphObj.OrgObjID   = BaseData.ItemInfo.OrgObjID;
    GraphObj.Mode       = BaseData.Mode;

    if( TempData.TouchPlot.Size() != 0 )
        GraphObj.TouchPlot_Range = TempData.TouchPlot_Range;
    else
        GraphObj.TouchPlot_Range = 0;

    if( TempData.RangePlot.Size() != 0 )
        GraphObj.RangePlot_Range = TempData.RangePlot_Range;
    else
        GraphObj.RangePlot_Range = 0;

    GraphObj.Name       = BaseData.RoleName;
    GraphObj.MaxHP      = int( TempData.Attr.Fin.MaxHP );
    GraphObj.HP         = BaseData.HP;
	GraphObj.MaxMP      = int( TempData.Attr.Fin.MaxMP );
	GraphObj.MP         = BaseData.MP;
	GraphObj.MaxSP      = int( TempData.Attr.Fin.MaxSP );		
	GraphObj.SP         = BaseData.SP;
    GraphObj.MoveSpeed  = TempData.Attr.Fin.MoveSpeed;
	//GraphObj.MoveSpeed  = MaxMoveSpeed();
//	TempData.Move.LMoveSpeed = GraphObj.MoveSpeed  = MoveSpeed();
    GraphObj.ModelRate	 = ModelSize(); 
    GraphObj.Level      = TempData.Attr.Ability->Level;
    GraphObj.NpcQuestID = SelfData.NpcQuestID;   
    GraphObj.Action     = TempData.Attr.LAction;

//	TempData.Attr.LAction._Action = TempData.Attr.Action._Action;
}

//-----------------------------------------------------------------------------------------
float   RoleDataEx::MoveSpeed( )
{
	if( IsWalk() == true )
		return TempData.Attr.Fin.MoveSpeed/3;

/*	if( TempData.Attr.Fin.MaxHP > BaseData.HP * 2 ) 
	{
		return __max( 5 , TempData.Attr.Fin.MoveSpeed * ( float( BaseData.HP) / (TempData.Attr.Fin.MaxHP) )* 2 );
	}*/

	return TempData.Attr.Fin.MoveSpeed ;

		/*
	if( IsPlayer() )
		return TempData.Attr.Fin.MoveSpeed;
	if( IsAttack() )
		return TempData.Attr.Fin.MoveSpeed;
	if( IsFollow() )
	{
		//檢查與目標的劇離
		if( Length( TargetID() ) < 30 )
			return 16;
		return TempData.Attr.Fin.MoveSpeed;
	}
*/
}
//-----------------------------------------------------------------------------------------
float   RoleDataEx::ModelSize( )
{
    return TempData.ModelSize;
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::MoveTarget( float X , float Y , float Z , float Dir )
{
    TempData.Move.Tx = X;
    TempData.Move.Ty = Y;
    TempData.Move.Tz = Z;

    int DTime = MoveTime( X , Y , Z );
    TempData.Move.ProcDelay = DTime;

    TempData.Move.Dx = ( X - BaseData.Pos.X ) / DTime;
    TempData.Move.Dy = ( Y - BaseData.Pos.Y ) / DTime;
    TempData.Move.Dz = ( Z - BaseData.Pos.Z ) / DTime;
    BaseData.Pos.Dir = Dir;
}
//-----------------------------------------------------------------------------------------
PathProcStruct* RoleDataEx::Move( )
{
    return &TempData.Move;
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::SecXZ( int X , int Z )
{
    TempData.Sys.SecX = X;
    TempData.Sys.SecZ = Z;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::SecX( )
{
    return TempData.Sys.SecX;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::SecZ( )
{
    return TempData.Sys.SecZ;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::SecRoomID( )
{
    return TempData.Sys.SecRoomID;
}
//-----------------------------------------------------------------------------------------
void     RoleDataEx::SecRoomID( int value )
{
    TempData.Sys.SecRoomID = value;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::Mode( )
{
    return BaseData.Mode._Mode;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::MaxHP( )
{
    return int(TempData.Attr.Fin.MaxHP);
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::HP( )
{
    return BaseData.HP;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::MaxMP( )
{
    return int(TempData.Attr.Fin.MaxMP);
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::MP( )
{
    return BaseData.MP;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::MaxSP( )
{
    return int(TempData.Attr.Fin.MaxSP);
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::SP( )
{
    return BaseData.SP;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::Level( )
{
    //return TempData.Attr.Ability->Level;
	return BaseData.AbilityList[ BaseData.Voc ].Level;
}
//-----------------------------------------------------------------------------------------
/*
void    RoleDataEx::PlayerGraph( PlayerGraphStruct& Graph )
{
    Graph.OrgObjID  = BaseData.ItemInfo.OrgObjID;
    Graph.Mode._Mode= Mode();
    Graph.MaxHP     = MaxHP();
    Graph.HP        = HP();
    Graph.MoveSpeed = MoveSpeed();
    Graph.ModelRate = ModelRate();
    Graph.Level     = Level();	

//    memcpy( Graph.Name , RoleName() , sizeof(Graph.Name) );
    Graph.Name = RoleName();

}
*/
//-----------------------------------------------------------------------------------------
const char*   RoleDataEx::RoleName( )
{
    return BaseData.RoleName.Begin();
}
void    RoleDataEx::RoleName( char* Name )
{
    //strncpy( BaseData.RoleName , Name , sizeof(BaseData.RoleName) );
    BaseData.RoleName = Name;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::DBID( )
{
    return Base.DBID;
}
//-----------------------------------------------------------------------------------------
/*
int     RoleDataEx::GuildID( )
{
	return SelfData.Guild.GuildID;
}
//-----------------------------------------------------------------------------------------
void     RoleDataEx::GuildID( int Value )
{
	SelfData.Guild.GuildID = Value;
}
*/
//-----------------------------------------------------------------------------------------
/*
void    RoleDataEx::SetValue(  char*  TypeName , float Value )
{
    RoleValueName_ENUM Type;
    if( stricmp( TypeName , "HP" ) == 0 )
        Type = EM_RoleValue_HP;
    else if( stricmp( TypeName , "MP" ) == 0 )
        Type = EM_RoleValue_MP;
    else if( stricmp( TypeName , "X" ) == 0 )
        Type = EM_RoleValue_X;
    else if( stricmp( TypeName , "Y" ) == 0 )
        Type = EM_RoleValue_Y;
    else if( stricmp( TypeName , "Z" ) == 0 )
        Type = EM_RoleValue_Z;
    else if( stricmp( TypeName , "Dir" ) == 0 )
        Type = EM_RoleValue_Dir;

    SetValue( Type , Value );
}
*/


void    RoleDataEx::SetValue(  RoleValueName_ENUM Type , int Value )
{
	SetValue( Type , (float)Value );
}
//設定或修改數值
void	RoleDataEx::SetValue( RoleValueName_ENUM Type , float Value )
{
    unsigned ID = Type - EM_RoleValue_SkillValue;
    if( ID < _MAX_SKILLVALUE_TYPE )
    {
        TempData.Attr.SkillValue->Skill[ID]  = Value;
        Net_FixRoleValue( Type , (float)Value );
        return;
    }
/*
	ID = Type - EM_RoleValue_NormalMagic;
	if( ID < _MAX_NormalSkill_COUNT_  )
	{
		TempData.Attr.Ability->MagicPoint[ID] = BaseData.Skill.MainJob[ ID ].Point = (int)Value;
		TempData.UpdateInfo.ReSetTalbe = true;
		TempData.UpdateInfo.SkillPointChange = true;
		Net_FixRoleValue( Type , (float)Value );
		return;
	}

	ID = Type - EM_RoleValue_SPMagic;
	if( ID < _MAX_SPSkill_COUNT_ )
	{
		BaseData.Skill.SP[ ID ].Point = (int)Value;
		TempData.UpdateInfo.ReSetTalbe = true;
		TempData.UpdateInfo.SkillPointChange = true;
		Net_FixRoleValue( Type , (float)Value );
		return;
	}
    */
    switch( Type )
    {
    case EM_RoleValue_X:
        BaseData.Pos.X = (float)Value;
        break;

    case EM_RoleValue_Y:
        BaseData.Pos.Y = (float)Value;
        break;

    case EM_RoleValue_Z:
        BaseData.Pos.Z = (float)Value;
        break;

    case EM_RoleValue_Dir:
        BaseData.Pos.Dir = (float)Value;
        break;
	case EM_RoleValue_HP:
		if( BaseData.HP == (int)Value )
			return;

		BaseData.HP = (int)Value;
		break;

	case EM_RoleValue_MP:
		if( BaseData.MP == (int)Value )
			return;

		BaseData.MP = (int)Value;
		break;

	case EM_RoleValue_SP:
		if( BaseData.SP == (int)Value )
			return;

		BaseData.SP = (int)Value;
		break;

	case EM_RoleValue_RACE:
		if( BaseData.Race == (Race_ENUM)(int)Value )
			return;

		BaseData.Race = (Race_ENUM)(int)Value;
		TempData.UpdateInfo.ReSetTalbe = true;
		break;
	case EM_RoleValue_VOC:
		if( BaseData.Voc == (Voc_ENUM)(int)Value )
			return;
		BaseData.Voc = (Voc_ENUM)(int)Value;
		TempData.UpdateInfo.ReSetTalbe = true;
		break;

	case EM_RoleValue_VOC_SUB:
		if( BaseData.Voc_Sub == (Voc_ENUM)(int)Value )
			return;
		BaseData.Voc_Sub = (Voc_ENUM)(int)Value;
		TempData.UpdateInfo.ReSetTalbe = true;
		break;

	case EM_RoleValue_SEX:
		if( BaseData.Sex == (Sex_ENUM)(int)Value )
			return;

		BaseData.Sex = (Sex_ENUM)(int)Value;
		TempData.UpdateInfo.ReSetTalbe = true;
		break;
	case EM_RoleValue_EXP:
		if( TempData.Attr.Ability->EXP == (int)Value )
			return;

		TempData.Attr.Ability->EXP = (int)Value;
		TempData.UpdateInfo.ExpChange = true;
		break;
	case EM_RoleValue_LV:
		if( TempData.Attr.Ability->Level == (int)Value )
			return;

		TempData.Attr.Ability->Level = (int)Value;
		TempData.Attr.Level = (int)Value;
		TempData.UpdateInfo.LvChange = true;
		break;

	case EM_RoleValue_STR:
		if( TempData.Attr.Ability->STR == (int)Value )
			return;

		TempData.Attr.Ability->STR = (int)Value;
		TempData.UpdateInfo.Recalculate = true;
		break;
	case EM_RoleValue_STA:
		if( TempData.Attr.Ability->STA == (int)Value )
			return;

		TempData.Attr.Ability->STA = (int)Value;
		TempData.UpdateInfo.Recalculate = true;
		break;
	case EM_RoleValue_INT:
		if( TempData.Attr.Ability->INT == (int)Value )
			return;

		TempData.Attr.Ability->INT = (int)Value;
		TempData.UpdateInfo.Recalculate = true;
		break;
	case EM_RoleValue_MND:
		if( TempData.Attr.Ability->MND == (int)Value )
			return;

		TempData.Attr.Ability->MND = (int)Value;
		TempData.UpdateInfo.Recalculate = true;
		break;
	case EM_RoleValue_AGI:
		if( TempData.Attr.Ability->AGI == (int)Value )
			return;

		TempData.Attr.Ability->AGI = (int)Value;
		TempData.UpdateInfo.Recalculate = true;
		break;

	case EM_RoleValue_Point:
		if( TempData.Attr.Ability->Point == (int)Value )
			return;

		TempData.Attr.Ability->Point = (int)Value;
		break;
	case EM_RoleValue_SkillPoint:
		if( TempData.Attr.Ability->SkillPoint == (int)Value )
			return;

		TempData.Attr.Ability->SkillPoint = (int)Value;
		break;

	case EM_RoleValue_Famous:
		if( BaseData.Famous == (int)Value )
			return;

		BaseData.Famous = (int)Value;
		break;
	case EM_RoleValue_KeyItemOn:
		if( BaseData.KeyItem.GetFlag( (int)Value ) == true )
			return;

		BaseData.KeyItem.SetFlagOn( (int)Value );
		break;
	case EM_RoleValue_KeyItemOff:
		if( BaseData.KeyItem.GetFlag( (int)Value ) == false )
			return;

		BaseData.KeyItem.SetFlagOff( (int)Value );
		break;
	
		//---------------------------------------------------------------------------------------
		//劇情需要的數值        
		//---------------------------------------------------------------------------------------
	case EM_RoleValue_IsWalk:
		IsWalk( Value != 0 );
		break;
     default:

        return;
    }
    Net_FixRoleValue( Type , (float)Value );

}
void    RoleDataEx::AddValue(  RoleValueName_ENUM Type , float  Value )
{
	if( Value == 0 )
		return;

	unsigned ID = Type - EM_RoleValue_SkillValue;
	if( ID < _MAX_SKILLVALUE_TYPE )
	{
		TempData.Attr.SkillValue->Skill[ID]  += Value;
		Net_FixRoleValue( Type , (float)Value );
		return;
	}
	AddValue( Type , (int)Value );

}
//設定或修改數值
void	RoleDataEx::AddValue( RoleValueName_ENUM Type , int Value )
{	
    if( Value == 0 )
        return;
/*
    unsigned ID = Type - EM_RoleValue_NormalMagic;
    if( ID < _MAX_NormalSkill_COUNT_ )
    {
        Value = Value + TempData.Attr.Ability->MagicPoint[ID];
        TempData.Attr.Ability->MagicPoint[ID] = Value;
        BaseData.Skill.MainJob[ ID ].Point = Value;
        Net_FixRoleValue( Type , (float)Value );
        return;
    }

    ID = Type - EM_RoleValue_SPMagic;
    if( ID < _MAX_SPSkill_COUNT_ )
    {
        Value += BaseData.Skill.SP[ ID ].Point;
        BaseData.Skill.SP[ ID ].Point += Value;
        Net_FixRoleValue( Type , (float)Value );
        return;
    }
*/

    switch( Type )
    {
    case EM_RoleValue_HP:

        Value = BaseData.HP += (int)Value;        
        break;

    case EM_RoleValue_MP:
        Value = BaseData.MP += (int)Value;
        break;

    case EM_RoleValue_SP:
        Value = BaseData.SP += (int)Value;
        break;

    case EM_RoleValue_EXP:
        Value = TempData.Attr.Ability->EXP += (int)Value;        
        break;
    case EM_RoleValue_LV:
        Value = TempData.Attr.Ability->Level += (int)Value;
        TempData.Attr.Level = TempData.Attr.Ability->Level;
        TempData.UpdateInfo.LvChange = true;
        break;

    case EM_RoleValue_STR:
        Value = TempData.Attr.Ability->STR += (int)Value;
        TempData.UpdateInfo.Recalculate = true;
        break;
    case EM_RoleValue_STA:
        Value = TempData.Attr.Ability->STA += (int)Value;
        TempData.UpdateInfo.Recalculate = true;
        break;
    case EM_RoleValue_INT:
        Value = TempData.Attr.Ability->INT += (int)Value;
        TempData.UpdateInfo.Recalculate = true;
        break;
    case EM_RoleValue_MND:
        Value = TempData.Attr.Ability->MND += (int)Value;
        TempData.UpdateInfo.Recalculate = true;
        break;
    case EM_RoleValue_AGI:
        Value = TempData.Attr.Ability->AGI += (int)Value;
        TempData.UpdateInfo.Recalculate = true;
        break;

    case EM_RoleValue_Point:
        Value = TempData.Attr.Ability->Point += (int)Value;
        break;
    case EM_RoleValue_SkillPoint:
        Value = TempData.Attr.Ability->SkillPoint += (int)Value;
        break;
    case EM_RoleValue_Famous:
        Value = BaseData.Famous += (int)Value;
        break;
    default:
        return;
    }
    Net_FixRoleValue( Type , (float)Value );

}

int	    RoleDataEx::GetValue( RoleValueName_ENUM Type  )
{
    switch( Type )
    {
    case EM_RoleValue_HP:
        return BaseData.HP;
        
    case EM_RoleValue_MP:
        return BaseData.MP;

    case EM_RoleValue_SP:
        return BaseData.SP;

    case EM_RoleValue_MaxHP:
        return (int)TempData.Attr.Fin.MaxHP;

    case EM_RoleValue_MaxMP:
        return (int)TempData.Attr.Fin.MaxMP;

    case EM_RoleValue_MaxSP:
        return (int)TempData.Attr.Fin.MaxSP;

    case EM_RoleValue_X:
        return (int)BaseData.Pos.X;

    case EM_RoleValue_Y:
        return (int)BaseData.Pos.Y;

    case EM_RoleValue_Z:
        return (int)BaseData.Pos.Z;

    case EM_RoleValue_Dir:
        return (int)BaseData.Pos.Dir;

    case EM_RoleValue_RACE:
        return BaseData.Race;

    case EM_RoleValue_VOC:
        return BaseData.Voc;

	case EM_RoleValue_VOC_SUB:
		return BaseData.Voc_Sub;

    case EM_RoleValue_SEX:
        return BaseData.Sex;

    case EM_RoleValue_EXP:
        return TempData.Attr.Ability->EXP;

    case EM_RoleValue_LV:
        return TempData.Attr.Ability->Level;

    case EM_RoleValue_STR:
        return TempData.Attr.Ability->STR;

    case EM_RoleValue_STA:
        return TempData.Attr.Ability->STA;

    case EM_RoleValue_INT:
        return TempData.Attr.Ability->INT;

    case EM_RoleValue_MND:
        return TempData.Attr.Ability->MND;

    case EM_RoleValue_AGI:
        return TempData.Attr.Ability->AGI;

    case EM_RoleValue_Point:
        return TempData.Attr.Ability->Point;

    case EM_RoleValue_SkillPoint:
        return TempData.Attr.Ability->SkillPoint;
    //---------------------------------------------------------------------------------------
    //劇情需要的數值        
    //---------------------------------------------------------------------------------------
    case EM_RoleValue_IsNPC:
        if( IsNPC() )
            return 1;
        return 0;
    case EM_RoleValue_IsPlayer:
        if( IsPlayer() )
            return 1;
        return 0;
    case EM_RoleValue_OrgID:
        return OrgObjID();

	case EM_RoleValue_PID:
		return SelfData.PID;

	case EM_RoleValue_IsWalk:
		return IsWalk();
    //---------------------------------------------------------------------------------------
    default:
        return 0;
    }

}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::ProxyID( int Value )
{
    TempData.Sys.ProxyID = Value;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::ProxyID( )
{
    return TempData.Sys.ProxyID;
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::SetInitNPC( GameObjDbStructEx* TempDB )
{
    BaseData.Voc  = (Voc_ENUM)TempDB->NPC.Vocation;
    BaseData.Race = (Race_ENUM)TempDB->NPC.Race;
    BaseData.Sex  = (Sex_ENUM)TempDB->NPC.Sex;
    BaseData.Voc_Sub = EM_Vocation_None;


    TempData.Attr.Ability = &BaseData.AbilityList[ BaseData.Voc ];
    TempData.Attr.SkillValue = &BaseData.SkillValue;
	TempData.Attr.Bas.Resist = TempDB->NPC.Resist;

    
    TempData.Attr.Ability->STR = TempDB->NPC.STR;
    TempData.Attr.Ability->STA = TempDB->NPC.STA;
    TempData.Attr.Ability->MND = TempDB->NPC.MND;
    TempData.Attr.Ability->INT = TempDB->NPC.INT;
    TempData.Attr.Ability->AGI = TempDB->NPC.AGI;

    if( TempDB->NPC.LevelRange > 1 )
        TempData.Attr.Ability->Level = TempDB->NPC.Level  + rand() % TempDB->NPC.LevelRange;
    else
        TempData.Attr.Ability->Level = TempDB->NPC.Level ;

    if( TempData.Attr.Ability->Level > 100 )
        TempData.Attr.Ability->Level  = 100;

    TempData.Attr.Level = TempData.Attr.Ability->Level;
    TempData.Attr.Level_Sub = 0;
	TempData.Attr.Bas.MoveSpeed_Per = float( TempDB->NPC.MoveSpeed );

	TempData.NPCHate.Init( );

    //裝備設定
    BaseData.EQ.MainHand.Count      = 1;
    BaseData.EQ.MainHand.OrgObjID   = TempDB->NPC.MainHandEQ[ rand() % _MAX_NPC_EQSEL_COUNT_ ];
    BaseData.EQ.SecondHand.Count    = 1;
    BaseData.EQ.SecondHand.OrgObjID = TempDB->NPC.SecHandEQ[ rand() % _MAX_NPC_EQSEL_COUNT_ ];

	//移動資訊初始化
	memset( &TempData.Move , 0 , sizeof(TempData.Move ) );

	//技能設定
//	TempData.Attr.SkillValue = &TempData.Attr.MaxSkillValue;

	IsWalk( true );
}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::SetInitItem( GameObjDbStructEx* TempDB )
{
    BaseData.Voc_Sub = EM_Vocation_None;
    TempData.Attr.Ability = &BaseData.AbilityList[0];
    TempData.Attr.SkillValue   = &BaseData.SkillValue;
}
//-----------------------------------------------------------------------------------------
int     RoleDataEx::MirrorCount( )
{
    return TempData.Sys.MirrorCount;
}
//-----------------------------------------------------------------------------------------
bool    RoleDataEx::IsDestroy()
{
    if( SelfData.LiveTime == -1 )
        return false;

	return RoleDataEx::CheckTime( SelfData.LiveTime ) == false;

}
//-----------------------------------------------------------------------------------------
void    RoleDataEx::Destroy()
{
	SelfData.LiveTime = RoleDataEx::G_SysTime;
}
//-----------------------------------------------------------------------------------------
BaseAbilityStruct*	RoleDataEx::Ability()
{
    return &BaseData.AbilityList[ BaseData.Voc ];
}
//-----------------------------------------------------------------------------------------
bool	RoleDataEx::SetAttack(  int TargetID )
{
    RoleDataEx* Target = St_GetRoleData( TargetID );
    if( Target == NULL )
        return false;

    return SetAttack( Target );
}
//設定攻擊某人
bool	RoleDataEx::SetAttack( RoleDataEx* Target )
{
    //檢查目標可不可攻擊
    if( !CheckAttackable( Target ) )
        return false;

    if( TempData.AI.TargetID != Target->GUID() )
    {
        TempData.AI.TargetID	= Target->GUID();
        TempData.AI.AttackCount = 1;
    }
    else
    {
        //目前不設定因時差的而累積的次數
        TempData.AI.AttackCount ++;

        if( TempData.AI.AttackCount <= 0 )
            TempData.AI.AttackCount = 1;

        if( TempData.AI.AttackCount  > 2 )
            TempData.AI.AttackCount  = 2;

    }

    if(     IsAttack() == false 
        &&  IsNPC() )  
    {
        IsAttack( true );
        CalHate( Target , 1 );
    }
    else
    {
        IsAttack( true );
    }

    return true;
}
//-----------------------------------------------------------------------------------------------
//設定跟隨某人
bool	RoleDataEx::SetFollow( RoleDataEx* Target )
{
    if( !CheckMoveable() )
        return false;

    TempData.AI.TargetID	= Target->GUID();
    TempData.Attr.Action.Follow	= true;
//    TempData.AI.MoveAiType = EM_NPC_MOVETYPE_FOLLOW;

    return true;
}
//-----------------------------------------------------------------------------------------------
//設定停止攻擊
bool	RoleDataEx::SetAtkFolOff( )
{
    if( TempData.Attr.Action.Attack == false)
        return false;

	//if( IsNPC() )
	//	IsWalk( true );

//    if( IsNPC() )
    ClearHate( );

    TempData.Attr.Action.Attack = false;
    TempData.Attr.Action.Follow = false;
    TempData.AI.AttackCount = 0;	
    TempData.AI.TargetID = -1;

//    TempData.AI.MoveAiType = EM_NPC_MOVETYPE_NORMAL;
    return true;
}
//-----------------------------------------------------------------------------------------------
void    RoleDataEx::Dead( bool Value )
{
    TempData.Attr.Action.Dead = Value;
    TempData.AI.ActionType	= Value? EM_ActionType_DEAD : EM_ActionType_NORMAL;
}
//-----------------------------------------------------------------------------------------------
//取得升級需要的 Exp
int    RoleDataEx::GetLVExp( )
{
    //if( TempData.Attr.Level - 1 >=  _MAX_LEVEL_ || TempData.Attr.Voc >= )

    return RoleDataEx::RoleExp[ TempData.Attr.Level - 1  ][ TempData.Attr.Voc ];
}
//----------------------------------------------------------------------------------------
int		RoleDataEx::GetExp()
{
	return TempData.Attr.Ability->EXP;
}
//----------------------------------------------------------------------------------------
void RoleDataEx::InitNPCData( )
{
    //取得物件資料
    GameObjDbStructEx* OrgDB	= St_GetObjDB( BaseData.ItemInfo.OrgObjID );
    if( OrgDB == NULL )
        return;

	//關閉攻擊狀態
	SetAtkFolOff();

    //設定等級與偏差資料
    SetInitNPC( OrgDB );

	
    TempData.Attr.Action._Action = 0;
	TempData.Attr.LAction._Action = 0;
//	TempData.Attr.Bas.Resist = OrgDB->NPC.Resist;

	//清除 Buff
	BaseData.Buff.Clear();
	TempData.Attr.ReSetTable();
	//TempData.Attr.Init_MidValue();
	ReCalculateMagicAndEQ( );

    TempData.Attr.Calculate();
	//TempData.Attr.
	

    TempData.AI.TargetID = -1;
    TempData.AI.LTargetID = -1;

    TempData.NPCHate.Init( );

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


}
//-----------------------------------------------------------------------------------------------
//設定Coldown
bool		RoleDataEx::SetMagicColdown( MagicColdownClassENUM	ColdownClass , int ColdownType , int ColdownTime , int ColdownTimeAllMagic )
{

	if( ColdownTimeAllMagic != 0 )
	{
		BaseData.Coldown.AllMagic = ColdownTimeAllMagic;
		
		if( BaseData.Coldown.NeedUpdatePos.Find( DEF_COLDOWN_ALL_POS ) == -1 )
			BaseData.Coldown.NeedUpdatePos.Push_Back( DEF_COLDOWN_ALL_POS );
	}

	if( ColdownTime == 0 )
		return true;

	int Pos = -1;

	switch( ColdownClass )
	{
	case EM_MagicColdownClass_None	:		//沒有
		return true;
	case EM_MagicColdownClass_Job	:		//職業類型

		Pos = DEF_COLDOWN_JOB_POS + ColdownType;
		break;
	case EM_MagicColdownClass_EQ	:		//裝備類型
		Pos = DEF_COLDOWN_EQ_POS + ColdownType;
		break;
	case EM_MagicColdownClass_Item	:		//物品類型
		Pos = DEF_COLDOWN_ITEM_POS + ColdownType;
		break;
	}
	
	if( Pos == -1 || Pos >= DEF_MAX_COLDOWN_COUNT_ALL )
		return false;

	BaseData.Coldown.All[ Pos ] = ColdownTime;

	if( BaseData.Coldown.NeedUpdatePos.Find( Pos ) == -1 )
		BaseData.Coldown.NeedUpdatePos.Push_Back( Pos );		

    return true;
}

//檢查Coldwon
bool    RoleDataEx::CheckMagicColdown( MagicColdownClassENUM	ColdownClass , int ColdownType )
{
	if( BaseData.Coldown.AllMagic > 0 )
		return false;


	int Pos = -1;

	switch( ColdownClass )
	{
	case EM_MagicColdownClass_None	:		//沒有
		return true;
	case EM_MagicColdownClass_Job	:		//職業類型

		Pos = DEF_COLDOWN_JOB_POS + ColdownType;
		break;
	case EM_MagicColdownClass_EQ	:		//裝備類型
		Pos = DEF_COLDOWN_EQ_POS + ColdownType;
		break;
	case EM_MagicColdownClass_Item	:		//物品類型
		Pos = DEF_COLDOWN_ITEM_POS + ColdownType;
		break;
	}

	if( Pos == -1 || Pos >= DEF_MAX_COLDOWN_COUNT_ALL )
		return false;

	if( BaseData.Coldown.All[ Pos ] > 0 )
		return false;

	return true;
}
//-----------------------------------------------------------------------------------------------
//定時處理Coldown
void	RoleDataEx::ColdownProc( )
{
	MagicColdownStruct& Coldown = BaseData.Coldown;
	for( int i = 0 ; i < Coldown.NeedUpdatePos.Size() ; i++ )
	{
		int Pos = Coldown.NeedUpdatePos[i];
		Coldown.All[ Pos ] --;
		if( Coldown.All[ Pos ]  <= 0 )
		{
			Coldown.NeedUpdatePos.Erase( i );
			i--;
			//是否要處發事件
			//....
		}
	}

	//煉製的Coldown
	for( int i = 0 ; i < BaseData.RefineColdown.Size() ; i++ )
	{
		int& Coldown = BaseData.RefineColdown[i].Coldown;
		Coldown --;
		
		if( Coldown <= 0)
		{
			BaseData.RefineColdown.Erase( i );
			i--;
		}
	}

}
//-----------------------------------------------------------------------------------------------
//設定角色物件模式
void    RoleDataEx::SetMode( int Mode )
{
    BaseData.Mode._Mode = Mode;
}
//-----------------------------------------------------------------------------------------------
int     RoleDataEx::Level_Sub( )
{
    return TempData.Attr.Level_Sub;
}
//-----------------------------------------------------------------------------------------------
int    RoleDataEx::AttackTargetID()
{
    if( IsAttack() == false )
        return -1;

    return TempData.AI.TargetID;
}
int    RoleDataEx::OrgObjID()
{
    return BaseData.ItemInfo.OrgObjID;
}
int    RoleDataEx::TargetID()
{
    return TempData.AI.TargetID;
}
//-----------------------------------------------------------------------------------------------
float	RoleDataEx::GetSkillValue( SkillValueTypeENUM SkillID )
{
	if( SkillID >= _MAX_SKILL_COUNT_ )
		return 0;

	return TempData.Attr.Fin.SkillValue.Skill[ SkillID ];
}
//取得武器的技能質
float	RoleDataEx::GetWeaponSkillValue( GameObjectWeaponENUM SkillID )
{
	SkillValueTypeENUM SkillType;
	switch( SkillID )
	{
	case EM_Weapon_Unarmed:			// Unarmed空手
		SkillType = EM_SkillValueType_Unarmed;
		break;
	case EM_Weapon_Blade:           // 劍
		SkillType = EM_SkillValueType_Blade;
		break;
	case EM_Weapon_Dagger:          // 匕首
		SkillType = EM_SkillValueType_Dagger;
		break;
	case EM_Weapon_Wand:            // 權杖
		SkillType = EM_SkillValueType_Wand;
		break;
	case EM_Weapon_Axe:             // 斧
		SkillType = EM_SkillValueType_Axe;
		break;
	case EM_Weapon_Bludgeon:        // 鎚棍棒
		SkillType = EM_SkillValueType_Bludgeon;
		break;
	case EM_Weapon_Claymore:        // 雙手劍
		SkillType = EM_SkillValueType_Claymore;
		break;
	case EM_Weapon_Staff:           // 杖
		SkillType = EM_SkillValueType_Staff;
		break;
	case EM_Weapon_2H_Axe:          // 雙手斧
		SkillType = EM_SkillValueType_2H_Axe;
		break;
	case EM_Weapon_2H_Hammer:       // 雙手鎚
		SkillType = EM_SkillValueType_2H_Hammer;
		break;
	case EM_Weapon_Polearm:			// 槍(長矛)
		SkillType = EM_SkillValueType_Polearm;
		break;
	case EM_Weapon_Bow:				// 遠程武器 弓
		SkillType = EM_SkillValueType_Bow;
		break;
	case EM_Weapon_CossBow:			// 遠程武器 十字弓
		SkillType = EM_SkillValueType_CossBow;
		break;
	case EM_Weapon_Gun:				// 遠程武器 槍
		SkillType = EM_SkillValueType_Gun;
		break;
	default:
		return 0;
	}
	return TempData.Attr.Fin.SkillValue.Skill[ SkillType ];
}
//-----------------------------------------------------------------------------------------------

void	RoleDataEx::AddWeaponSkillValue( int TargetLV , GameObjectWeaponENUM SkillID , float Exp )
{
	SkillValueTypeENUM SkillType;
	switch( SkillID )
	{
	case EM_Weapon_Unarmed:			// Unarmed空手
		SkillType = EM_SkillValueType_Unarmed;
		break;
	case EM_Weapon_Blade:           // 劍
		SkillType = EM_SkillValueType_Blade;
		break;
	case EM_Weapon_Dagger:          // 匕首
		SkillType = EM_SkillValueType_Dagger;
		break;
	case EM_Weapon_Wand:            // 權杖
		SkillType = EM_SkillValueType_Wand;
		break;
	case EM_Weapon_Axe:             // 斧
		SkillType = EM_SkillValueType_Axe;
		break;
	case EM_Weapon_Bludgeon:        // 鎚棍棒
		SkillType = EM_SkillValueType_Bludgeon;
		break;
	case EM_Weapon_Claymore:        // 雙手劍
		SkillType = EM_SkillValueType_Claymore;
		break;
	case EM_Weapon_Staff:           // 杖
		SkillType = EM_SkillValueType_Staff;
		break;
	case EM_Weapon_2H_Axe:          // 雙手斧
		SkillType = EM_SkillValueType_2H_Axe;
		break;
	case EM_Weapon_2H_Hammer:       // 雙手鎚
		SkillType = EM_SkillValueType_2H_Hammer;
		break;
	case EM_Weapon_Polearm:			// 槍(長矛)
		SkillType = EM_SkillValueType_Polearm;
		break;
	case EM_Weapon_Bow:				// 遠程武器 弓
		SkillType = EM_SkillValueType_Bow;
		break;
	case EM_Weapon_CossBow:			// 遠程武器 十字弓
		SkillType = EM_SkillValueType_CossBow;
		break;
	case EM_Weapon_Gun:				// 遠程武器 槍
		SkillType = EM_SkillValueType_Gun;
		break;
	default:
		return;
	}
	AddSkillValue( TargetLV , SkillType , Exp );
}

//計算每打擊一次獲得的技能熟練度
void	RoleDataEx::AddSkillValue( int TargetLV , SkillValueTypeENUM SkillID , float Exp )
{
	if( IsNPC() )
		return;
	if( (unsigned) SkillID >= _MAX_SKILLVALUE_TYPE )
		return;
	if( Exp < 0 )
		return;

	float& SkillValue = TempData.Attr.SkillValue->Skill[ SkillID ];
	float MaxSkillValue = TempData.Attr.MaxSkillValue.GetSkill(SkillID);
	if( SkillValue >= MaxSkillValue )
		return;

	int SkillLV =  (int)(SkillValue / ( MaxSkillValue / TempData.Attr.Level ));
	int DLV = TargetLV - SkillLV -1;

	if( SkillLV >= _MAX_LEVEL_ )
		return;

	float SkillExp = Exp * GetBaseDLvExp( DLV )/ SkillValueExp[SkillLV];

	SkillValue += SkillExp;
	Net_FixRoleValue( (RoleValueName_ENUM)(EM_RoleValue_SkillValue+SkillID) , (float)SkillValue );
}
//-----------------------------------------------------------------------------------------------
float		RoleDataEx::GetBaseDLvExp( int DLV )
{
	static float ExpArr[21]={ 5, 10, 20,30,40,50,60,70,80,90,100
							,125,150,175,200,225,250,275,300,325,350 };

	DLV += 10;
	if( DLV < 0 )
		DLV = 0;

	if( DLV > 20 )
		DLV = 20;

	return ExpArr[DLV];
}