void CCharacterPhysicsSupport::in_Hit( SHit &H, bool is_killing )
{
	m_sv_hit = H;
	m_hit_valide_time = Device.dwTimeGlobal + hit_valide_time;
	if( m_EntityAlife.use_simplified_visual	( ) || esRemoved == m_eState )
		return;
	if( m_flags.test( fl_block_hit ) )
	{
		VERIFY2( !m_EntityAlife.g_Alive( ),
			make_string("entity [%s][%d] is dead", m_EntityAlife.Name(), m_EntityAlife.ID()).c_str());
		if( Device.dwTimeGlobal - m_EntityAlife.GetLevelDeathTime( ) >= 2000 )
			m_flags.set(fl_block_hit,FALSE);
		else return;
	}

	//is_killing = is_killing || ( m_eState==esAlive && !m_EntityAlife.g_Alive( ) );
	if( m_EntityAlife.g_Alive( ) && is_killing && H.type( ) == ALife::eHitTypeExplosion && H.damage( ) > 70.f )
		CPHDestroyable::Destroy( );
	
	if( ( !m_EntityAlife.g_Alive() || is_killing ) )
		m_character_shell_control.set_kill_hit( H );

	if(!m_pPhysicsShell&&is_killing)
		KillHit( H );

	if( m_flags.test(fl_use_hit_anims) && Type() != etBitting && !m_flags.test(fl_death_anim_on) ) //&& Type() == etStalker
	{
		m_hit_animations.PlayHitMotion( H.direction( ), H.bone_space_position(), H.bone( ), m_EntityAlife );
	}

	if( !( m_pPhysicsShell && m_pPhysicsShell->isActive( ) ) )
	{
		if( !is_killing && m_EntityAlife.g_Alive( ) )
			m_PhysicMovementControl->ApplyHit( H.direction( ), H.phys_impulse( ), H.type( ) );
	} else {
#ifdef	DEBUG
		if( is_killing && death_anim_debug &&  !is_imotion( m_interactive_motion ) )
		{
				Msg( "death anim: applied fatal impulse dir: (%f,%f,%f), value: (%f) ", H.dir.x,H.dir.y,H.dir.z, H.impulse );
		}
#endif
		m_pPhysicsShell->applyHit( H.bone_space_position( ), H.direction( ), H.phys_impulse( ), H.bone(), H.type( ) );
	}
}
Exemple #2
0
void CCar::PHHit(SHit &H)
{
	if(!m_pPhysicsShell)	return;
	if(m_bone_steer==H.bone()) return;
	if(CPHUpdateObject::IsActive())
	{
		Fvector vimpulse;vimpulse.set(H.direction());
		vimpulse.mul( H.phys_impulse( ) );
		vimpulse.y *=GravityFactorImpulse();
		float mag=vimpulse.magnitude();
		if(!fis_zero(mag))
		{
			 vimpulse.mul(1.f/mag);
			 m_pPhysicsShell->applyHit(H.bone_space_position(),vimpulse,mag,H.bone(),H.type());
		}
		
	} else
	{
		m_pPhysicsShell->applyHit( H.bone_space_position(), H.direction(), H.phys_impulse(), H.bone(), H.type() );
	}
}
type_motion::edirection	type_motion::dir( CEntityAlive& ea, const SHit& H, float& angle  )
{
	
	Fvector dir = H.direction();
	dir.y = 0;
	float m = dir.magnitude();
	if( fis_zero( m ) )
	{
		edirection dr;
		dr = (edirection) ::Random.randI( 0, (s32) not_definite );
		VERIFY( dr < not_definite );
		return	dr;
	}
	dir.mul( 1.f / m );

	Fvector z_dir = { ea.XFORM().k.x, 0.f, ea.XFORM().k.z };
	Fvector x_dir =  { ea.XFORM().i.x, 0.f, ea.XFORM().i.z };
	z_dir.normalize_safe();x_dir.normalize_safe();

	float front_factor	= dir.dotproduct( z_dir );
	float sidefactor	= dir.dotproduct( x_dir );

	if( _abs( front_factor ) > M_SQRT1_2 )
	{
		float sign = front_factor < 0.f ? -1.f : 1.f;

		angle = atan2( -sign * sidefactor, sign * front_factor );	

		return sign < 0.f ? front : back;
	} 
	else
	{
		float sign = sidefactor > 0.f ? 1.f : -1.f;

		angle = atan2( sign * front_factor, sign * sidefactor );	
		return sign > 0.f ? left : right;
	}

}
void CAI_Stalker::Hit(SHit* pHDS)
{
	//хит может меняться в зависимости от ранга (новички получают больше хита, чем ветераны)
	SHit HDS = *pHDS;
	HDS.add_wound = true;
	
	float hit_power = HDS.power * m_fRankImmunity;

	if(m_boneHitProtection && HDS.hit_type == ALife::eHitTypeFireWound)
	{
		float BoneArmor = m_boneHitProtection->getBoneArmor(HDS.bone());
		float ap = HDS.armor_piercing;
		if(!fis_zero(BoneArmor, EPS))
		{
			if(ap > BoneArmor)
			{
				float d_hit_power = (ap - BoneArmor) / ap;
				if(d_hit_power < m_boneHitProtection->m_fHitFracNpc)
					d_hit_power = m_boneHitProtection->m_fHitFracNpc;

				hit_power *= d_hit_power;
				VERIFY(hit_power>=0.0f);
			}
			else
			{
				hit_power *= m_boneHitProtection->m_fHitFracNpc;
				HDS.add_wound = false;
			}
		}

		if ( wounded() ) //уже лежит => добивание
		{
			hit_power = 1000.f;
		}
	}
	HDS.power = hit_power;

	if (g_Alive())
	{
		bool already_critically_wounded = critically_wounded();

		if (!already_critically_wounded)
		{
			const CCoverPoint		*cover = agent_manager().member().member(this).cover();
			if ( !invulnerable() && cover && HDS.initiator() &&
				( HDS.initiator()->ID() != ID() ) && !fis_zero( HDS.damage() ) && brain().affect_cover() )
			{
				agent_manager().location().add( xr_new<CDangerCoverLocation>(cover,Device.dwTimeGlobal,DANGER_INTERVAL,DANGER_DISTANCE) );
			}
		}

		const CEntityAlive	*entity_alive = smart_cast<const CEntityAlive*>(HDS.initiator());
		if (entity_alive && !wounded()) {
			if (is_relation_enemy(entity_alive))
				sound().play		(eStalkerSoundInjuring);
//			else
//				sound().play		(eStalkerSoundInjuringByFriend);
		}

		int							weapon_type = -1;
		if (best_weapon())
			weapon_type				= best_weapon()->object().ef_weapon_type();

		if	(
				!wounded() &&
				!already_critically_wounded)
		{
			bool					became_critically_wounded = update_critical_wounded(HDS.boneID,HDS.power);
			if	(
				!became_critically_wounded &&
				animation().script_animations().empty() &&
				(HDS.bone() != BI_NONE)
			)
			{
				Fvector					D;
				float					yaw, pitch;
				D.getHP					(yaw,pitch);

	#pragma todo("Dima to Dima : forward-back bone impulse direction has been determined incorrectly!")
				float					power_factor = m_power_fx_factor * HDS.damage() / 100.f;
				clamp					(power_factor,0.f,1.f);

				//IKinematicsAnimated		*tpKinematics = smart_cast<IKinematicsAnimated*>(Visual());
				IKinematics *tpKinematics = smart_cast<IKinematics*>(Visual());
	#ifdef DEBUG
				tpKinematics->LL_GetBoneInstance	(HDS.bone());
				if (HDS.bone() >= tpKinematics->LL_BoneCount()) {
					Msg					("tpKinematics has no bone_id %d",HDS.bone());
					HDS._dump			();
				}
	#endif
//				int						fx_index = iFloor(tpKinematics->LL_GetBoneInstance(HDS.bone()).get_param(1) + (angle_difference(movement().m_body.current.yaw,-yaw) <= PI_DIV_2 ? 0 : 1));
//				if (fx_index != -1)
//					animation().play_fx	(power_factor,fx_index);
			}
			else {
				if (!already_critically_wounded && became_critically_wounded) {
					if (HDS.who) {
						CAI_Stalker		*stalker = smart_cast<CAI_Stalker*>(HDS.who);
						if ( stalker && stalker->g_Alive() )
							stalker->on_critical_wound_initiator	(this);
					}
				}
			}
		}
	}

	if ( g_Alive() && ( !m_hit_callback || m_hit_callback( &HDS ) ) )
	{
		float const damage_factor	= invulnerable() ? 0.f : 100.f;
		memory().hit().add			( damage_factor*HDS.damage(), HDS.direction(), HDS.who, HDS.boneID );
	}

	//conditions().health()			= 1.f;

	inherited::Hit					( &HDS );
}
Exemple #5
0
void	CPhysicsShellHolder::PHHit( SHit &H )
{
	if(H.phys_impulse() >0)
		if(m_pPhysicsShell) m_pPhysicsShell->applyHit(H.bone_space_position(),H.direction(),H.phys_impulse(),H.bone(),H.type());
}