void CStalkerAnimationManager::legs_process_direction		(float yaw)
{
	float						switch_factor = legs_switch_factor();
	stalker_movement_manager_smart_cover		&movement = object().movement();
	float						head_current = movement.head_orientation().current.yaw;
	float						left = left_angle(yaw,head_current);
	float						test_angle_forward = right_forward_angle;
	float						test_angle_backward = left_forward_angle;
	if (left) {
		test_angle_forward		= left_forward_angle;
		test_angle_backward		= right_forward_angle;
	}
	test_angle_backward			= PI - test_angle_backward;

	float						difference = angle_difference(yaw,head_current);

	if (difference <= test_angle_forward)
		legs_assign_direction			(switch_factor,eMovementDirectionForward);
	else {
		if (difference > test_angle_backward)
			legs_assign_direction		(switch_factor,eMovementDirectionBackward);
		else
			if (left)
				legs_assign_direction	(switch_factor,eMovementDirectionLeft);
			else
				legs_assign_direction	(switch_factor,eMovementDirectionRight);
	}
	
	movement.m_body.target.yaw	= yaw + direction_angles[m_current_direction];
}
Exemple #2
0
void CAI_Rat::SelectAnimation(const Fvector& /**_view/**/, const Fvector& /**_move/**/, float /**speed/**/)
{
	IKinematicsAnimated	*tpVisualObject = smart_cast<IKinematicsAnimated*>(Visual());
	MotionID			tpGlobalAnimation;

	if (!g_Alive()) {
		for (int i=0 ;i<2; ++i) {
			if (m_tRatAnimations.tNormal.tGlobal.tpaDeath[i] == m_tpCurrentGlobalAnimation) {
				tpGlobalAnimation = m_tpCurrentGlobalAnimation;
				break;
			}
		}
		if (!tpGlobalAnimation) {
			if (m_tpCurrentGlobalAnimation == m_tRatAnimations.tNormal.tGlobal.tpaIdle[1])
				tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tpaDeath[0];
			else
				tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tpaDeath[::Random.randI(0,2)];
		}
	}
	else {
		if (m_bFiring)
			tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tpaAttack[2];
		else
			if (angle_difference(movement().m_body.target.yaw,movement().m_body.current.yaw) <= MIN_TURN_ANGLE)
				if (m_fSpeed < 0.2f) {
					if (m_bStanding)
						tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tpaIdle[1];
					else
						tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tpaIdle[0];
				}
				else
					if (_abs(m_fSpeed - m_fAttackSpeed) < EPS_L)
						tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tRunAttack;
					else
						if (_abs(m_fSpeed - m_fMaxSpeed) < EPS_L)
							tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tRun.fwd;
						else
							tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tWalk.fwd;
			else {
				if (left_angle(-movement().m_body.target.yaw,-movement().m_body.current.yaw))
//					tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tpaIdle[0];
					tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tpTurnLeft;
				else
//					tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tpaIdle[0];
					tpGlobalAnimation = m_tRatAnimations.tNormal.tGlobal.tpTurnRight;
			}
	}

	if (tpGlobalAnimation != m_tpCurrentGlobalAnimation)
		m_tpCurrentGlobalBlend = tpVisualObject->PlayCycle(m_tpCurrentGlobalAnimation = tpGlobalAnimation);

#ifdef DEBUG
	if (psAI_Flags.is(aiAnimation)) {
		IKinematicsAnimated	*skeleton_animated = smart_cast<IKinematicsAnimated*>(Visual());
		Msg					("%6d %s animation : %s (%f,%f)",Device.dwTimeGlobal,"Global",skeleton_animated->LL_MotionDefName_dbg(m_tpCurrentGlobalAnimation),movement().m_body.current.yaw,movement().m_body.target.yaw);
	}
#endif
}
MotionID CStalkerAnimationManager::legs_no_move_animation	()
{
	m_previous_speed			= 0.f;
	m_current_speed				= 0.f;

	if (!m_no_move_actual) {
		m_no_move_actual		= true;
		if (m_crouch_state_config == -1)
			m_crouch_state		= ::Random.randI(2);
		else
			m_crouch_state		= m_crouch_state_config;
	}

	m_change_direction_time		= Device.dwTimeGlobal;
	m_current_speed				= 0.f;

	EBodyState					body_state = this->body_state();
	const xr_vector<MotionID>	&animation = m_data_storage->m_part_animations.A[body_state].m_in_place->A;

	CStalkerMovementManager		&movement = object().movement();
	const SBoneRotation			&body_orientation = movement.body_orientation();
	float						current = body_orientation.current.yaw;
	float						target = body_orientation.target.yaw;
	if (angle_difference(target,current) < EPS_L) {

		float					head_current = movement.head_orientation().current.yaw;
		if ((movement.mental_state() != eMentalStateFree) || (!object().sight().turning_in_place() && (angle_difference(current,head_current) <= standing_turn_angle))) {
			if (movement.mental_state() == eMentalStateFree)
				return			(animation[1]);

			if (body_state == eBodyStateCrouch)
				return			(animation[m_crouch_state]);

			return				(animation[0]);
		}

		movement.m_body.target.yaw	= movement.head_orientation().target.yaw;
		target						= movement.m_body.target.yaw;
	}

	if (left_angle(current,target)) {
		if (movement.mental_state() == eMentalStateFree)
			return				(animation[4]);

		return					(animation[2]);
	}

	if (movement.mental_state() == eMentalStateFree)
		return					(animation[5]);

	return						(animation[3]);
}
MotionID CStalkerAnimationManager::legs_move_animation		()
{
	m_no_move_actual			= false;

	stalker_movement_manager_smart_cover		&movement = object().movement();

	VERIFY						(
		(movement.body_state() == eBodyStateStand) ||
		(movement.mental_state() != eMentalStateFree)
	);

	if (eMentalStateDanger != movement.mental_state()) {
		m_target_speed			= movement.speed(eMovementDirectionForward);
		m_last_non_zero_speed	= m_target_speed;

		return					(
			m_data_storage->m_part_animations.A[
				body_state()
			].m_movement.A[
				movement.movement_type()
			].A[
				eMovementDirectionForward
			].A[
				1
			]
		);
	}

	float						yaw,pitch;
	object().sight().GetDirectionAngles(yaw,pitch);

	yaw							= angle_normalize_signed(-yaw);;
	legs_process_direction		(yaw);

	float						body_current = movement.body_orientation().current.yaw;
	bool						left = left_angle(yaw,body_current);
	float						test_angle_forward = right_forward_angle;
	float						test_angle_backward = left_forward_angle;
	if (left) {
		test_angle_forward		= left_forward_angle;
		test_angle_backward		= right_forward_angle;
	}
	test_angle_backward			= PI - test_angle_backward;

	EMovementDirection			speed_direction;
	float						difference = angle_difference(yaw,body_current);

	if (difference <= test_angle_forward)
		speed_direction			= eMovementDirectionForward;
	else {
		if (difference > test_angle_backward)
			speed_direction		= eMovementDirectionBackward;
		else {
			if (left)
				speed_direction	= eMovementDirectionLeft;
			else
				speed_direction	= eMovementDirectionRight;
		}
	}

	if (m_previous_speed_direction != speed_direction) {
		if (m_change_direction_time < Device.dwTimeGlobal)
			m_change_direction_time	= Device.dwTimeGlobal;

		if (!legs_switch_factor()) {
			m_previous_speed		= 0.f;
			m_target_speed			= 0.f;
		}

		m_previous_speed_direction	= speed_direction;
	}

	m_target_speed				= movement.speed(speed_direction);
	m_last_non_zero_speed		= m_target_speed;

	return						(
		m_data_storage->m_part_animations.A[
			body_state()
		].m_movement.A[
			movement.movement_type()
		].A[
			speed_direction
		].A[
			0
		]
	);
}