Example #1
0
void CControlJump::hit_test() 
{
	if (m_object_hitted)	return;
	if (!m_data.target_object)	return;

	// ѕроверить на нанесение хита во врем¤ прыжка
	Fvector trace_from;
	m_object->Center(trace_from);

	collide::rq_result	l_rq;

	if (Level().ObjectSpace.RayPick(trace_from, m_object->Direction(), m_hit_trace_range, collide::rqtObject, l_rq, m_object)) {
		if ((l_rq.O == m_data.target_object) && (l_rq.range < m_hit_trace_range)) {
			m_object_hitted = true;
		}
	}

	if (!m_object_hitted && m_data.target_object) {
		
		m_object_hitted = true;
		// определить дистанцию до врага
		Fvector d;
		d.sub(m_data.target_object->Position(),m_object->Position());
		if (d.magnitude() > m_hit_trace_range) m_object_hitted = false;

		// проверка на  Field-Of-Hit
		float my_h,my_p;
		float h,p;

		m_object->Direction().getHP(my_h,my_p);
		d.getHP(h,p);

		float from	= angle_normalize(my_h - PI_DIV_6);
		float to	= angle_normalize(my_h + PI_DIV_6);

		if (!is_angle_between(h, from, to)) m_object_hitted = false;

		from	= angle_normalize(my_p - PI_DIV_6);
		to		= angle_normalize(my_p + PI_DIV_6);

		if (!is_angle_between(p, from, to)) m_object_hitted = false;

	} 

	if (m_object_hitted) 
		m_object->HitEntityInJump(smart_cast<CEntity*>(m_data.target_object));
}
void CControlManagerCustom::check_jump_over_physics()
{
	if (!m_man->path_builder().is_moving_on_path()) return;
	if (!m_man->check_start_conditions(ControlCom::eControlJump)) return;
	if (!m_object->check_start_conditions(ControlCom::eControlJump)) return;
	if (m_object->GetScriptControl()) return;

	Fvector prev_pos	= m_object->Position();
	float	dist_sum	= 0.f;

	for(u32 i = m_man->path_builder().detail().curr_travel_point_index(); i<m_man->path_builder().detail().path().size();i++) {
		const DetailPathManager::STravelPathPoint &travel_point = m_man->path_builder().detail().path()[i];

		// получить список объектов вокруг врага
		m_nearest.clear_not_free		();
		Level().ObjectSpace.GetNearest	(m_nearest,travel_point.position, m_object->Radius(), NULL);

		for (u32 k=0;k<m_nearest.size();k++) {
			CPhysicsShellHolder *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[k]);
			if (!obj || !obj->PPhysicsShell() || !obj->PPhysicsShell()->isActive() || (obj->Radius() < 0.5f)) continue;
			if (m_object->Position().distance_to(obj->Position()) < MAX_DIST_SUM / 2) continue;

			Fvector dir = Fvector().sub(travel_point.position, m_object->Position());

			// проверка на  Field-Of-View
			float	my_h	= m_object->Direction().getH();
			float	h		= dir.getH();

			float from	= angle_normalize(my_h - deg(8));
			float to	= angle_normalize(my_h + deg(8));

			if (!is_angle_between(h, from, to)) continue;

			dir = Fvector().sub(obj->Position(), m_object->Position());

			// вычислить целевую позицию для прыжка
			Fvector target;
			obj->Center(target);
			target.y += obj->Radius();
			// --------------------------------------------------------

			m_jump->setup_data().flags.set			(SControlJumpData::ePrepareSkip, true);
			m_jump->setup_data().target_object		= 0;
			m_jump->setup_data().target_position	= target;

			jump(m_jump->setup_data());

			return;
		}

		dist_sum += prev_pos.distance_to(travel_point.position);
		if (dist_sum > MAX_DIST_SUM) break;

		prev_pos = travel_point.position;
	}
}
void CControlAnimationBase::check_hit(MotionID motion, float time_perc)
{
	if (!m_object->EnemyMan.get_enemy()) return;
	const CEntityAlive *enemy = m_object->EnemyMan.get_enemy();

	SAAParam &params		= AA_GetParams(motion,time_perc);
	
	m_object->sound().play	(MonsterSound::eMonsterSoundAttackHit);

	bool should_hit = true;
	// определить дистанцию до врага
	Fvector d;
	d.sub(enemy->Position(),m_object->Position());
	if (d.magnitude() > params.dist) 
		should_hit = false;
	
	// проверка на  Field-Of-Hit
	float my_h,my_p;
	float h,p;

	m_object->Direction().getHP(my_h,my_p);
	d.getHP(h,p);
	
	float from	= angle_normalize(my_h + params.foh.from_yaw);
	float to	= angle_normalize(my_h + params.foh.to_yaw);
	
	if (!is_angle_between(h, from, to)) 
		should_hit = false;

	from		= angle_normalize(my_p + params.foh.from_pitch);
	to			= angle_normalize(my_p + params.foh.to_pitch);

	if (!is_angle_between(p, from, to)) 
		should_hit = false;

	if (should_hit) 
		m_object->HitEntity(enemy, params.hit_power, params.impulse, params.impulse_dir);

	m_object->MeleeChecker.on_hit_attempt(should_hit);
}