text: #include "stdafx.h"
  #include "chimera.h"
  #include "chimera_state_manager.h"
  #include "../../../../Include/xrRender/KinematicsAnimated.h"
  #include "../../../detail_path_manager.h"
  #include "../monster_velocity_space.h"
  #include "../../../level.h"
  //#include "../../../PhysicsShell.h"
  #include "../../../sound_player.h"
  #include "../control_animation_base.h"
  #include "../control_movement_base.h"
  #include "../control_path_builder_base.h"
  
  
  CChimera::CChimera ()
  {
  	StateMan							=	xr_new<CStateManagerChimera>	(this);
  	com_man().add_ability					(ControlCom::eControlJump);
  }
  
  CChimera::~CChimera ()
  {
  	xr_delete								(StateMan);
  }
  
  void   CChimera::Load (LPCSTR section)
  {
  	inherited::Load							(section);
  
  	anim().accel_load						(section);
  	anim().accel_chain_add					(eAnimWalkFwd,		eAnimRun);
  	anim().accel_chain_add					(eAnimWalkFwd,		eAnimRunTurnLeft);
  	anim().accel_chain_add					(eAnimWalkFwd,		eAnimRunTurnRight);
  	anim().accel_chain_add					(eAnimWalkDamaged,	eAnimRunDamaged);
  
  	anim().AddReplacedAnim					(&m_bDamaged, eAnimRun,		eAnimRunDamaged);
  	anim().AddReplacedAnim					(&m_bDamaged, eAnimWalkFwd,	eAnimWalkDamaged);
  	anim().AddReplacedAnim					(&m_bRunTurnLeft,	eAnimRun,		eAnimRunTurnLeft);
  	anim().AddReplacedAnim					(&m_bRunTurnRight,	eAnimRun,		eAnimRunTurnRight);
  
  
  	SVelocityParam &velocity_none		= 	move().get_velocity(MonsterMovement::eVelocityParameterIdle);	
  	SVelocityParam &velocity_turn		= 	move().get_velocity(MonsterMovement::eVelocityParameterStand);
  	SVelocityParam &velocity_walk		= 	move().get_velocity(MonsterMovement::eVelocityParameterWalkNormal);
  	SVelocityParam &velocity_run		= 	move().get_velocity(MonsterMovement::eVelocityParameterRunNormal);
  	SVelocityParam &velocity_walk_dmg	= 	move().get_velocity(MonsterMovement::eVelocityParameterWalkDamaged);
  	SVelocityParam &velocity_run_dmg	= 	move().get_velocity(MonsterMovement::eVelocityParameterRunDamaged);
  	SVelocityParam &velocity_steal		= 	move().get_velocity(MonsterMovement::eVelocityParameterSteal);
  
  	bool use_cop_anims = READ_IF_EXISTS( pSettings, r_bool, section, "use_cop_anims", false );
  	if ( use_cop_anims ) {
  	  m_velocity_rotate.Load( section, "Velocity_Rotate" );
  	  m_velocity_jump_start.Load( section, "Velocity_JumpStart" );
  	}
  	else {
  	  m_velocity_rotate.Load( section, "Velocity_Stand" );
  	  m_velocity_jump_start.Load( section, "Velocity_JumpGround" );
  	}
  	
  	anim().AddAnim	(eAnimStandIdle,		"stand_idle_",			-1, &velocity_none,		PS_STAND);
  
  	//@
  
  	IKinematicsAnimated*	KA			=	smart_cast<IKinematicsAnimated*>(Visual());
  	MotionID idle_motion_id1			=	KA->LL_MotionID("stand_idle_0");
  	MotionID idle_motion_id2			=	KA->LL_MotionID("stand_idle_1");
  	
  	if ( use_cop_anims ) {
  	  anim().AddAnim( eAnimWalkFwd,            "stand_walk_",           -1, &velocity_walk,     PS_STAND) ;
  	  anim().AddAnim( eAnimFastStandTurnLeft,  "stand_run_turn_90_ls_", -1, &m_velocity_rotate, PS_STAND );
  	  anim().AddAnim( eAnimFastStandTurnRight, "stand_run_turn_90_rs_", -1, &m_velocity_rotate, PS_STAND );
  	  anim().AddAnim( eAnimWalkDamaged,        "stand_walk_dmg_",       -1, &velocity_walk_dmg, PS_STAND );
  	  anim().AddAnim( eAnimSteal,              "stand_walk_",           -1, &velocity_steal,    PS_STAND );
  	  anim().AddAnim( eAnimPrepareAttack,      "stand_agressive_idle_", -1, &velocity_none,     PS_STAND );
  	  anim().AddAnim( eAnimRunTurnLeft,        "stand_run_turn_ls_",    -1, &velocity_run,      PS_STAND );
  	  anim().AddAnim( eAnimRunTurnRight,       "stand_run_turn_rs_",    -1, &velocity_run,      PS_STAND );
  	}
  	else {
  	  anim().AddAnim( eAnimWalkFwd,            "stand_walk_fwd_",       -1, &velocity_walk,     PS_STAND );
  	  anim().AddAnim( eAnimFastStandTurnLeft,  "stand_turn_ls_",        -1, &m_velocity_rotate, PS_STAND );
  	  anim().AddAnim( eAnimFastStandTurnRight, "stand_turn_ls_",        -1, &m_velocity_rotate, PS_STAND );
  	  anim().AddAnim( eAnimWalkDamaged,        "stand_walk_fwd_dmg_",   -1, &velocity_walk_dmg, PS_STAND );
  	  anim().AddAnim( eAnimSteal,              "stand_steal_",          -1, &velocity_steal,    PS_STAND );
  	  anim().AddAnim( eAnimPrepareAttack,      "stand_idle_",           -1, &velocity_none,     PS_STAND );
  	  anim().AddAnim( eAnimRunTurnLeft,        "stand_run_fwd_",        -1, &velocity_run,      PS_STAND );
  	  anim().AddAnim( eAnimRunTurnRight,       "stand_run_fwd_",        -1, &velocity_run,      PS_STAND );
  	}
  
  	anim().AddAnim	(eAnimLieIdle,			"stand_idle_",			-1, &velocity_none,		PS_LIE);
  	anim().AddAnim	(eAnimSleep,			"stand_idle_",			-1, &velocity_none,		PS_LIE);
  
  	anim().AddAnim	(eAnimStandTurnLeft,	"stand_turn_ls_",		-1, &velocity_turn,		PS_STAND);
  	anim().AddAnim	(eAnimStandTurnRight,	"stand_turn_rs_",		-1, &velocity_turn,		PS_STAND);
  
  	anim().AddAnim	(eAnimRun,				"stand_run_fwd_",		-1,	&velocity_run,		PS_STAND);
  	anim().AddAnim	(eAnimRunDamaged,		"stand_run_dmg_",		-1,	&velocity_run_dmg,	PS_STAND);
  	anim().AddAnim	(eAnimCheckCorpse,		"stand_check_corpse_",	-1,	&velocity_none,		PS_STAND);
  	anim().AddAnim	(eAnimEat,				"stand_eat_",			-1, &velocity_none,		PS_STAND);
  	anim().AddAnim	(eAnimAttack,			"stand_idle_",			-1, &velocity_turn,		PS_STAND);
  
  	anim().AddAnim	(eAnimLookAround,		"stand_idle_",			-1, &velocity_none,		PS_STAND);
  	anim().AddAnim	(eAnimDie,				"stand_idle_",			-1, &velocity_none,		PS_STAND);
  	anim().AddAnim	(eAnimThreaten,			"stand_idle_",			-1, &velocity_none,		PS_STAND);
  
  	anim().AddAnim	(eAnimUpperAttack,		"jump_attack_",			-1, &m_velocity_jump_start,	PS_STAND);
  
  	// link action
  	anim().LinkAction						(ACT_STAND_IDLE,	eAnimStandIdle);
  	anim().LinkAction						(ACT_SIT_IDLE,		eAnimLieIdle);
  	anim().LinkAction						(ACT_LIE_IDLE,		eAnimLieIdle);
  	anim().LinkAction						(ACT_WALK_FWD,		eAnimWalkFwd);
  	//anim().LinkAction						(ACT_WALK_BKWD,		eAnimDragCorpse);
  	anim().LinkAction						(ACT_RUN,			eAnimRun);
  	anim().LinkAction						(ACT_EAT,			eAnimEat);
  	anim().LinkAction						(ACT_SLEEP,			eAnimSleep);
  	anim().LinkAction						(ACT_REST,			eAnimLieIdle);
  	//anim().LinkAction						(ACT_DRAG,			eAnimDragCorpse);
  	anim().LinkAction						(ACT_ATTACK,		eAnimAttack);
  	anim().LinkAction						(ACT_STEAL,			eAnimSteal);
  	anim().LinkAction						(ACT_LOOK_AROUND,	eAnimLookAround);
  
  	m_attack_params.attack_radius			=	READ_IF_EXISTS(pSettings, r_float,section, "attack_radius",	    10.f);
  	m_attack_params.prepare_jump_timeout	=	READ_IF_EXISTS(pSettings, r_u32,  section, "prepare_jump_timeout",	2000);
  	m_attack_params.attack_jump_timeout		=	READ_IF_EXISTS(pSettings ,r_u32,  section, "attack_jump_timeout",	1000);
  	m_attack_params.stealth_timeout			=	READ_IF_EXISTS(pSettings ,r_u32,  section, "stealth_timeout",	2000);
  	m_attack_params.force_attack_distance	=	READ_IF_EXISTS(pSettings ,r_float,  section, "force_attack_distance",	8);
  	m_attack_params.num_attack_jumps		=	READ_IF_EXISTS(pSettings ,r_u32,  section, "num_attack_jumps",	4);
  	m_attack_params.num_prepare_jumps		=	READ_IF_EXISTS(pSettings ,r_u32,  section, "num_prepare_jumps",	2);
  #ifdef DEBUG	
  	anim().accel_chain_test					();
  #endif
  
  	PostLoad								(section);
  }
  
  EAction   CChimera::CustomVelocityIndex2Action (u32 velocity_index) 
  {
  	switch ( velocity_index ) 
  	{
  		case MonsterMovement::eChimeraVelocityParameterJumpGround:	return ACT_RUN;
  		case MonsterMovement::eChimeraVelocityParameterPrepare:		return ACT_RUN;
  	}
  
  	return ACT_STAND_IDLE;
  }
  
  void   CChimera::reinit ()
  {
  	inherited::reinit						();
  
  	move().load_velocity					(*cNameSect(), 
  											 "Velocity_JumpGround",
  											 MonsterMovement::eChimeraVelocityParameterJumpGround);
  
  	com_man().load_jump_data				(0,//"jump_attack_0",
  											 0,//"jump_attack_0",
  											 "jump_attack_1", 
  											 "jump_attack_2", 
  											 u32(-1),//MonsterMovement::eVelocityParameterRunNormal,
  											 MonsterMovement::eChimeraVelocityParameterJumpGround,
  											 0);
  }
  
  void   CChimera::CheckSpecParams (u32 spec_params)
  {
  // 	if ( (spec_params & ASP_THREATEN) == ASP_THREATEN )
  // 	{
  // 		anim().SetCurAnim(eAnimThreaten);
  // 	}
  // 	if ( (spec_params & ASP_ATTACK_RUN) == ASP_ATTACK_RUN ) 
  // 	{
  // 		anim().SetCurAnim(eAnimAttackRun);
  // 	}
  }
  
  void   CChimera::HitEntityInJump (const CEntity *pEntity)
  {
  	SAAParam &params					=	anim().AA_GetParams("jump_attack_1");
  	
  	HitEntity								(pEntity, params.hit_power, params.impulse, params.impulse_dir);
  }
  
  void   CChimera::jump (Fvector const &position, float const factor)
  {
  	com_man().script_jump					(position, factor);
  	sound().play							(MonsterSound::eMonsterSoundAggressive);
  }
  
  void CChimera::UpdateCL()
  {
  	inherited::UpdateCL						();
  }
  