void CPHCollisionDamageReceiver::Hit(u16 source_id,u16 bone_id,float power,const Fvector& dir,Fvector &pos )
{

	DAMAGE_BONES_I i=FindBone(bone_id);
	if(i==m_controled_bones.end())return;
	power*=i->second;
	if(power<hit_threthhold)return;
	
	NET_Packet		P;
	CPhysicsShellHolder *ph=PPhysicsShellHolder();
	SHit	HS;
	
	HS.GenHeader(GE_HIT,ph->ID());					//	ph->u_EventGen(P,GE_HIT,ph->ID());
	HS.whoID			= ph->ID();					//	P.w_u16		(ph->ID());
	HS.weaponID			= source_id;				//	P.w_u16		(source_id);
	HS.dir				= dir;						//	P.w_dir		(dir);
	HS.power			= power;					//	P.w_float	(power);
	HS.boneID			= s16(bone_id);				//	P.w_s16		(s16(bone_id));
	HS.p_in_bone_space	= pos;						//	P.w_vec3	(pos);
	HS.impulse			= 0.f;						//	P.w_float	(0.f);
	HS.hit_type			= (ALife::eHitTypeStrike);	//	P.w_u16		(ALife::eHitTypeStrike);
	HS.Write_Packet(P);						

	ph->u_EventSend(P);
}
Beispiel #2
0
//void CHangingLamp::Hit(float P,Fvector &dir, CObject* who,s16 element,
//					   Fvector p_in_object_space, float impulse, ALife::EHitType hit_type)
void	CHangingLamp::Hit					(SHit* pHDS)
{
	SHit	HDS = *pHDS;
	callback(GameObject::eHit)(
		lua_game_object(), 
		HDS.power,
		HDS.dir,
		smart_cast<const CGameObject*>(HDS.who)->lua_game_object(),
		HDS.bone()
		);

#ifdef HLAMP_AFFECT_IMMUNITIES
	HDS.power = CHitImmunity::AffectHit(HDS.power,HDS.hit_type);	
	inherited::Hit(pHDS);
#endif
	BOOL	bWasAlive		= Alive		() || light_render->get_active();

	if(m_pPhysicsShell) 
	   m_pPhysicsShell->applyHit(pHDS->p_in_bone_space,pHDS->dir,pHDS->impulse,pHDS->boneID,pHDS->hit_type);
	
	if (!bWasAlive) return;

	if (pHDS->boneID==light_bone)
	    SetHealth ( 0.f );
	else
	{
		float damage = pHDS->damage() * 100.f;
		Msg("DEBUG: %s health = %.3f, damage = %.3f", Name_script(), GetHealth(), damage);
		SetHealth(GetHealth() - damage);
	}
	if (bWasAlive && (!Alive()))		TurnOff	();
}
void CStalkerActionKillWounded::execute					()
{
	inherited::execute		();

	if (!object().memory().enemy().selected())
		return;

	const CEntityAlive		*enemy = object().memory().enemy().selected();
	object().sight().setup	(CSightAction(enemy,true));
	object().set_goal		(eObjectActionFire1,weapon_to_kill(&object()),MIN_QUEUE,MAX_QUEUE,MIN_INTERVAL,MAX_INTERVAL);

	if (object().memory().visual().visible_now(enemy) && object().can_kill_enemy() && !object().can_kill_member())
		return;

	// this is fake
	// but sometimes enemy can not be visible
	// when it plays animation inside another object
	// therefore we should use this ugly workaround
	// and hit enemy virtually
	NET_Packet				P;
	SHit					HS;
	HS.GenHeader			(GE_HIT, enemy->ID());
	HS.whoID				= object().ID();
	HS.weaponID				= weapon_to_kill(&object())->object().ID();
	HS.dir					= Fvector().set(0.f,0.f,1.f);
	HS.power				= 1.f;
	HS.boneID				= smart_cast<CKinematics*>((const_cast<CEntityAlive*>(enemy))->Visual())->LL_GetBoneRoot();
	HS.p_in_bone_space		= Fvector().set(0.f,0.f,0.f);
	HS.impulse				= 1.f;
	HS.hit_type				= ALife::eHitTypeWound;
	HS.Write_Packet			(P);
	object().u_EventSend	(P);
}
	bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle ) const	
	{
		
		if( H.initiator() !=  Level().CurrentControlEntity())
			return false;

		if(H.type() == ALife::eHitTypeExplosion)
		{
			edirection dr = dir( ea, H, angle );
			m = motion( dr );
			type_motion_diagnostic( "type_motion6: 7. √ранта", dr, ea, H, m );
			return true;
		}

		CObject* O = Level().Objects.net_Find( H.weaponID );
		if(!O)
		{
			m = MotionID();
			return false;
		}

		if( smart_cast<CExplosive*>( O ) != 0 )
		{	
			edirection dr = dir( ea, H, angle );
			m = motion(  dr );
			type_motion_diagnostic( "type_motion6: 7. √ранта - осколок", dr, ea, H, m );
			return true;
		}

		return false;
	}
Beispiel #5
0
void CAI_Rat::Exec_Action(float /**dt/**/)
{
	switch (m_tAction) {
		case eRatActionAttackBegin : {
			u32					dwTime = Device.dwTimeGlobal;
			sound().play	(eRatSoundAttack);//,0,0,m_dwHitInterval+1,m_dwHitInterval);
			if (memory().enemy().selected() && memory().enemy().selected()->g_Alive() && (dwTime - m_dwStartAttackTime > m_dwHitInterval)) {
				m_bActionStarted = true;
				m_dwStartAttackTime = dwTime;
				Fvector tDirection;
				Fvector position_in_bone_space;
				position_in_bone_space.set(0.f,0.f,0.f);
				tDirection.sub(memory().enemy().selected()->Position(),this->Position());
				vfNormalizeSafe(tDirection);
				
				if (this->Local() && memory().enemy().selected()) {
					CEntityAlive	*entity_alive = const_cast<CEntityAlive*>(memory().enemy().selected());
					VERIFY			(entity_alive);

//					entity_alive->Hit(m_fHitPower,tDirection,this,0,position_in_bone_space,0);
					u16			id_to = entity_alive->ID();
					u16			id_from = ID();
					NET_Packet	l_P;
					SHit		HS;
					HS.GenHeader(GE_HIT, id_to);					//					u_EventGen	(l_P,GE_HIT, id_to);
					HS.whoID			= (id_from);				//					l_P.w_u16	(id_from);
					HS.weaponID			= (id_from);				//					l_P.w_u16	(id_from);
					HS.dir				= (tDirection);				//					l_P.w_dir	(tDirection);
					HS.power			= (m_fHitPower);			//					l_P.w_float	(m_fHitPower);
					HS.boneID			= (0);						//					l_P.w_s16	(0);
					HS.p_in_bone_space	= (position_in_bone_space);	//					l_P.w_vec3	(position_in_bone_space);
					HS.impulse			= (0.f);					//					l_P.w_float	(0.f);
					HS.hit_type			= (ALife::eHitTypeWound);	//					l_P.w_u16	((u16)ALife::eHitTypeWound);
					HS.Write_Packet(l_P);
					u_EventSend	(l_P);
				}
			}
			else
				m_bActionStarted = false;
			break;
		}
		case eRatActionAttackEnd : {
			m_bActionStarted = false;
			break;
		}
		default:
			break;
	}
}
Beispiel #6
0
void CExplosive::ExplodeWaveProcessObject(collide::rq_results& storage, CPhysicsShellHolder*l_pGO)
{
	Fvector	l_goPos;
	if(l_pGO->Visual())		l_pGO->Center	(l_goPos); 
	else					return; //мне непонятно зачем наносить хит от взрыва по объектам не имеющим вижуал - поэтому игнорируем

#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
		DBG_OpenCashedDraw();
		
	}
#endif

	float l_effect=ExplosionEffect(storage,this,l_pGO,m_vExplodePos,m_fBlastRadius);
	float l_impuls	= m_fBlastHitImpulse * l_effect;
	float l_hit		= m_fBlastHit * l_effect;

	if(l_impuls > .001f||l_hit> 0.001) 
	{
	
		Fvector l_dir;l_dir.sub(l_goPos,m_vExplodePos);
		
		float rmag=_sqrt(m_fUpThrowFactor*m_fUpThrowFactor+1.f+2.f*m_fUpThrowFactor*l_dir.y);
		l_dir.y += m_fUpThrowFactor;
		//rmag -модуль l_dir после l_dir.y += m_fUpThrowFactor, модуль=_sqrt(l_dir^2+y^2+2.*(l_dir,y)),y=(0,m_fUpThrowFactor,0) (до этого модуль l_dir =1)
		l_dir.mul(1.f/rmag);//перенормировка
 		NET_Packet		P;
		SHit	HS;
		HS.GenHeader(GE_HIT, l_pGO->ID());			//		cast_game_object()->u_EventGen		(P,GE_HIT,l_pGO->ID());
		HS.whoID  =Initiator();						//		P.w_u16			(Initiator());
		HS.weaponID = cast_game_object()->ID();		//		P.w_u16			(cast_game_object()->ID());
		HS.dir = l_dir;								//		P.w_dir			(l_dir);
		HS.power = l_hit;							//		P.w_float		(l_hit);
		HS.p_in_bone_space = l_goPos;				//		P.w_vec3		(l_goPos);
		HS.impulse = l_impuls;						//		P.w_float		(l_impuls);
		HS.hit_type = (m_eHitTypeBlast);			//		P.w_u16			(u16(m_eHitTypeBlast));
		HS.boneID = 0;								//		P.w_s16			(0);
		HS.Write_Packet(P);
		cast_game_object()->u_EventSend		(P);
	}
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
		DBG_ClosedCashedDraw(100000);

	}
#endif
}
void CBaseMonster::Hit_Wound(CObject *object, float value, const Fvector &dir, float impulse) 
{
	NET_Packet	P;
	SHit		HS;
	HS.GenHeader(GE_HIT, object->ID());														//	u_EventGen	(P,GE_HIT, object->ID());
	HS.whoID			= (ID());															//	P.w_u16		(ID());
	HS.weaponID			= (ID());															//	P.w_u16		(ID());
	HS.dir				= (dir);															//	P.w_dir		(dir);
	HS.power			= (value);															//	P.w_float	(value);
	HS.boneID			= (smart_cast<IKinematics*>(object->Visual())->LL_GetBoneRoot());	//	P.w_s16		(smart_cast<IKinematics*>(object->Visual())->LL_GetBoneRoot());
	HS.p_in_bone_space	= (Fvector().set(0.f,0.f,0.f));										//	P.w_vec3	(Fvector().set(0.f,0.f,0.f));
	HS.impulse			= (impulse);														//	P.w_float	(impulse);
	HS.hit_type			= (ALife::eHitTypeWound);											//	P.w_u16		(u16(ALife::eHitTypeWound));
	HS.Write_Packet(P);
	u_EventSend	(P);
}
void CBaseMonster::Hit_Psy(CObject *object, float value) 
{
	NET_Packet		P;
	SHit			HS;
	HS.GenHeader		(GE_HIT, object->ID());				//					//	u_EventGen		(P,GE_HIT, object->ID());				// 
	HS.whoID			= (ID());									// own		//	P.w_u16			(ID());									// own
	HS.weaponID			= (ID());									// own		//	P.w_u16			(ID());									// own
	HS.dir				= (Fvector().set(0.f,1.f,0.f));			// direction	//	P.w_dir			(Fvector().set(0.f,1.f,0.f));			// direction
	HS.power			= (value);								// hit value	//	P.w_float		(value);								// hit value
	HS.boneID			= (BI_NONE);								// bone		//	P.w_s16			(BI_NONE);								// bone
	HS.p_in_bone_space	= (Fvector().set(0.f,0.f,0.f));							//	P.w_vec3		(Fvector().set(0.f,0.f,0.f));			
	HS.impulse			= (0.f);												//	P.w_float		(0.f);									
	HS.hit_type			= (ALife::eHitTypeTelepatic);							//	P.w_u16			(u16(ALife::eHitTypeTelepatic));
	HS.Write_Packet	(P);
	u_EventSend		(P);
}
Beispiel #9
0
void CActor::g_Physics			(Fvector& _accel, float jump, float dt)
{
	// Correct accel
	Fvector		accel;
	accel.set					(_accel);
	hit_slowmo					-=	dt;
	if (hit_slowmo<0)			hit_slowmo = 0.f;

	accel.mul					(1.f-hit_slowmo);
	
	if(g_Alive())
	{
	if(mstate_real&mcClimb&&!cameras[eacFirstEye]->bClampYaw)accel.set(0.f,0.f,0.f);
	character_physics_support()->movement()->Calculate			(accel,cameras[cam_active]->vDirection,0,jump,dt,false);
	bool new_border_state=character_physics_support()->movement()->isOutBorder();
	if(m_bOutBorder!=new_border_state && Level().CurrentControlEntity() == this)
	{
		SwitchOutBorder(new_border_state);
	}
	character_physics_support()->movement()->GetPosition		(Position());
	character_physics_support()->movement()->bSleep				=false;
	}

	if (Local() && g_Alive()) {
		if (character_physics_support()->movement()->gcontact_Was)
			Cameras().AddCamEffector		(xr_new<CEffectorFall> (character_physics_support()->movement()->gcontact_Power));
		if (!fis_zero(character_physics_support()->movement()->gcontact_HealthLost))	{
			const ICollisionDamageInfo* di=character_physics_support()->movement()->CollisionDamageInfo();
			Fvector hdir;di->HitDir(hdir);
			SetHitInfo(this, NULL, 0, Fvector().set(0, 0, 0), hdir);
			//				Hit	(m_PhysicMovementControl->gcontact_HealthLost,hdir,di->DamageInitiator(),m_PhysicMovementControl->ContactBone(),di->HitPos(),0.f,ALife::eHitTypeStrike);//s16(6 + 2*::Random.randI(0,2))
			if (Level().CurrentControlEntity() == this)
			{
				SHit HDS = SHit(character_physics_support()->movement()->gcontact_HealthLost,hdir,di->DamageInitiator(),character_physics_support()->movement()->ContactBone(),di->HitPos(),0.f,di->HitType());
//				Hit(&HDS);

				NET_Packet	l_P;
				HDS.GenHeader(GE_HIT, ID());
				HDS.whoID = di->DamageInitiator()->ID();
				HDS.weaponID = di->DamageInitiator()->ID();
				HDS.Write_Packet(l_P);

				u_EventSend	(l_P);
			}
		}
	}
}
	bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle ) const
	{
		m = MotionID();
		if( H.initiator() !=  Level().CurrentControlEntity())
			return false;
		VERIFY( ea.Visual( ) );
		IKinematics *K = ea.Visual()->dcast_PKinematics();
		VERIFY( K );
		if( is_bone_head( *K, H.bone() ) )
		{
			edirection dr = dir( ea, H, angle );
			m = motion( dr );
			type_motion_diagnostic( " type_motion3: 4.	’едшот (по веро¤тности), кроме 5 (4)", dr, ea, H, m );
			return true;
		}
		return false;
	}
	bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle ) const	
	{
		if( H.initiator() !=  Level().CurrentControlEntity())
			return false;
		m = MotionID();
		VERIFY( ea.Visual( ) );
		IKinematics *K = ea.Visual()->dcast_PKinematics();
		VERIFY( K );

		if(is_snipper( H.weaponID ) && !is_bone_head( *K, H.bone() ))
		{
			edirection dr = dir( ea, H, angle );
			m = motion( dr );
			type_motion_diagnostic( "type_motion5: 6.	—найперка в тело", dr, ea, H, m );
			return true;
		}
		return false;
	}
	bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle )	const
	{
		m = MotionID();
		if( H.initiator() !=  Level().CurrentControlEntity())
			return false;
		
		VERIFY( ea.Visual( ) );
		IKinematics *K = ea.Visual()->dcast_PKinematics();
		VERIFY( K );
		if( !is_bone_head( *K, H.bone() ))
			return false;

		//CAI_Stalker* s = ea.cast_stalker	();
		CCharacterPhysicsSupport* chs = ea.character_physics_support();
		if( !chs || chs->Type( ) == CCharacterPhysicsSupport::etBitting )
			return false;

		VERIFY( chs->movement() );
		
		const Fvector stalker_velocity = chs->movement()->GetVelocity();
		const float stalker_speed = stalker_velocity.magnitude();
		const float min_stalker_speed = 3.65f;
		if(stalker_speed < min_stalker_speed )
			return false;

		const Fvector stalker_velocity_dir = Fvector().mul( stalker_velocity, 1.f/stalker_speed );

		const Fvector dir_to_actor = Fvector().sub( H.initiator()->Position(), ea.Position() ).normalize_safe();

		const float front_angle_cos = _cos( deg2rad ( 20.f ) );
		
		if( stalker_velocity_dir.dotproduct(dir_to_actor) < front_angle_cos )
			return false;

		if( type_motion::front != type_motion::dir( ea, H, angle )  )
			return false;
		Fvector p;
		if( Fvector().sub( H.initiator()->Position(), global_hit_position( p, ea, H ) ).magnitude() > 30.f )
			return false;

		m = motion( front );
		type_motion_diagnostic( " type_motion0: 1. = »нерционное движение вперед от попадани¤ в голову ", front, ea, H, m );
		return true;
	}
Beispiel #13
0
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( ) );
	}
}
void CBreakableObject::ProcessDamage()
{
	NET_Packet			P;
	SHit				HS;
	HS.GenHeader		(GE_HIT, ID());
	HS.whoID			= (ID());			
	HS.weaponID			= (ID());			
	HS.dir				= (m_contact_damage_dir);
	HS.power			= (m_max_frame_damage);					
	HS.boneID			= (PKinematics(Visual())->LL_GetBoneRoot());				
	HS.p_in_bone_space	= (m_contact_damage_pos);
	HS.impulse			= (0.f);
	HS.hit_type			= (ALife::eHitTypeStrike);
	HS.Write_Packet		(P);
	
	u_EventSend			(P);

	m_max_frame_damage		= 0.f;
	b_resived_damage		=false;
}
Beispiel #15
0
//void CCar::Hit(float P,Fvector &dir,CObject * who,s16 element,Fvector p_in_object_space, float impulse, ALife::EHitType hit_type)
void	CCar::Hit							(SHit* pHDS)
{

	SHit	HDS = *pHDS;
	//if(CDelayedActionFuse::isActive()||Initiator()==u16(-1)&&HDS.hit_type==ALife::eHitTypeStrike)
	//{
	//	HDS.power=0.f;
	//}

	//if(HDS.who->ID()!=ID())
	//{
	//	CExplosive::SetInitiator(HDS.who->ID());
	//}
	WheelHit(HDS.damage(),HDS.bone(),HDS.hit_type);
	DoorHit(HDS.damage(),HDS.bone(),HDS.hit_type);
	float hitScale=1.f,woundScale=1.f;
	if(HDS.hit_type!=ALife::eHitTypeStrike) CDamageManager::HitScale(HDS.bone(), hitScale, woundScale);
	HDS.power *= GetHitImmunity(HDS.hit_type)*hitScale;

	inherited::Hit(&HDS);
	if(!CDelayedActionFuse::isActive())
	{
		CDelayedActionFuse::CheckCondition(GetfHealth());
	}
	CDamagableItem::HitEffect();
//	if(Owner()&&Owner()->ID()==Level().CurrentEntity()->ID())
//		CurrentGameUI()->UIMainIngameWnd->CarPanel().SetCarHealth(GetfHealth());
}
Beispiel #16
0
void CRadioactiveZone::UpdateWorkload					(u32	dt)
{
	if (IsEnabled() && GameID() != GAME_SINGLE)
	{	
		OBJECT_INFO_VEC_IT it;
		Fvector pos; 
		XFORM().transform_tiny(pos,CFORM()->getSphere().P);
		for(it = m_ObjectInfoMap.begin(); m_ObjectInfoMap.end() != it; ++it) 
		{
			if( !(*it).object->getDestroy() && (*it).object->CLS_ID == CLSID_OBJECT_ACTOR)
			{
				//=====================================
				NET_Packet	l_P;
				l_P.write_start();
				l_P.read_start();

				float dist = (*it).object->Position().distance_to(pos);
				float power = Power(dist)*dt/1000;
///				Msg("Zone Dist %f, Radiation Power %f, ", dist, power);

				SHit HS;
				HS.GenHeader(GE_HIT, (*it).object->ID());
				HS.whoID  =ID();
				HS.weaponID = ID();
				HS.dir = Fvector().set(0,0,0);
				HS.power = power;
				HS.boneID = BI_NONE;
				HS.p_in_bone_space = Fvector().set(0, 0, 0);
				HS.impulse = 0.0f;
				HS.hit_type = ALife::eHitTypeRadiation;
				
				HS.Write_Packet_Cont(l_P);

				(*it).object->OnEvent(l_P, HS.PACKET_TYPE);
				//=====================================
			};
		}
	}
	inherited::UpdateWorkload(dt);
}
Beispiel #17
0
void CRadioactiveZone::UpdateWorkload					(u32	dt)
{
	if (IsEnabled() && GameID() != eGameIDSingle)
	{	
		OBJECT_INFO_VEC_IT it;
		Fvector pos; 
		XFORM().transform_tiny(pos,CFORM()->getSphere().P);
		for(it = m_ObjectInfoMap.begin(); m_ObjectInfoMap.end() != it; ++it) 
		{
			if( !(*it).object->getDestroy() && smart_cast<CActor*>((*it).object))
			{
				//=====================================
				NET_Packet	l_P;
				l_P.write_start();
				l_P.read_start();

				float dist			= (*it).object->Position().distance_to(pos);
				float power			= Power(dist,nearest_shape_radius(it))*dt/1000;

				SHit				HS;
				HS.GenHeader		(GE_HIT, (*it).object->ID());
				HS.whoID			= ID();
				HS.weaponID			= ID();
				HS.dir				= Fvector().set(0,0,0);
				HS.power			= power;
				HS.boneID			= BI_NONE;
				HS.p_in_bone_space	= Fvector().set(0, 0, 0);
				HS.impulse			= 0.0f;
				HS.hit_type			= m_eHitTypeBlowout;
				
				HS.Write_Packet_Cont(l_P);

				(*it).object->OnEvent(l_P, HS.PACKET_TYPE);
				//=====================================
			};
		}
	}
	inherited::UpdateWorkload(dt);
}
	bool predicate( CEntityAlive& ea, const SHit& H, MotionID &m, float &angle ) const	
	{
		m = MotionID();
		if( H.initiator() !=  Level().CurrentControlEntity())
		return false;
		
		CObject* O = Level().Objects.net_Find( H.weaponID );
		if(!O)
			return false;
		//static_cast<CGameObject*>(O)->cast_weapon()
		CWeaponShotgun* s = smart_cast< CWeaponShotgun* >( static_cast<CGameObject*>(O) );
		if(!s)
			return false;
		Fvector p;
		const	float max_distance = 20.f;
		if(Fvector().sub(H.initiator()->Position(),global_hit_position( p, ea, H )).magnitude() > max_distance)
			return false;
		edirection dr = dir( ea, H, angle );
		m = motion( dr );
		type_motion_diagnostic( " type_motion2: 3.	Ўотган ", dr, ea, H, m );
		return true;
	}
void type_motion_diagnostic( LPCSTR message, type_motion::edirection dr, const CEntityAlive& ea, const SHit& H, const MotionID &m )
{
#ifdef DEBUG

	if(! death_anim_debug )
		return;
	
	IKinematicsAnimated *KA = smart_cast<IKinematicsAnimated*>( ea.Visual() );
	VERIFY( KA );
	IKinematics *K  = smart_cast<IKinematics*>( ea.Visual() );
	LPCSTR bone_name = "not_definite";
	if( H.bone() != BI_NONE )
	{
		CBoneData& bd = K->LL_GetData( H.bone() );
		bone_name = bd.name.c_str();
	}
	LPCSTR motion_name = "not_set";
	if( m.valid() )
		motion_name = KA->LL_MotionDefName_dbg( m ).first;

	Msg( "death anims: %s, dir: %s, motion: %s,  obj: %s, model: %s, bone: %s " ,message ,motion_dirs[ dr ].name, motion_name, ea.cName().c_str(), ea.cNameVisual().c_str(), bone_name );

#endif
}
Beispiel #20
0
void CCustomZone::CreateHit	(	u16 id_to, 
								u16 id_from, 
								const Fvector& hit_dir, 
								float hit_power, 
								s16 bone_id, 
								const Fvector& pos_in_bone, 
								float hit_impulse, 
								ALife::EHitType hit_type)
{
	if (OnServer())
	{
		if(m_owner_id != u32(-1) )
			id_from	= (u16)m_owner_id;

		NET_Packet			l_P;
		Fvector hdir		= hit_dir;
		SHit Hit			= SHit(hit_power, hdir, this, bone_id, pos_in_bone, hit_impulse, hit_type, 0.0f, false);		
		Hit.GenHeader		(GE_HIT, id_to);
		Hit.whoID			= id_from;
		Hit.weaponID		= this->ID();
		Hit.Write_Packet	(l_P);
		u_EventSend			(l_P);
	};
}
//void CDestroyablePhysicsObject::Hit							(float P,Fvector &dir,CObject *who,s16 element,Fvector p_in_object_space, float impulse,  ALife::EHitType hit_type)
void	CDestroyablePhysicsObject::Hit					(SHit* pHDS)
{
	SHit	HDS = *pHDS;
	callback(GameObject::eHit)(
		lua_game_object(), 
		HDS.power,
		HDS.dir,
		smart_cast<const CGameObject*>(HDS.who)->lua_game_object(),
		HDS.bone()
		);
	HDS.power=CHitImmunity::AffectHit(HDS.power,HDS.hit_type);
	float hit_scale=1.f,wound_scale=1.f;
	CDamageManager::HitScale(HDS.bone(),hit_scale,wound_scale);
	HDS.power*=hit_scale;
//	inherited::Hit(P,dir,who,element,p_in_object_space,impulse,hit_type);
	inherited::Hit(&HDS);
	m_fHealth-=HDS.power;
	if(m_fHealth<=0.f)
	{
//		CPHDestroyable::SetFatalHit(SHit(P,dir,who,element,p_in_object_space,impulse,hit_type));
		CPHDestroyable::SetFatalHit(HDS);
		if(CPHDestroyable::CanDestroy())Destroy();
	}
}
void CScriptGameObject::Hit(CScriptHit *tpLuaHit)
{
	CScriptHit		&tLuaHit = *tpLuaHit;
	NET_Packet		P;
	SHit			HS;
	HS.GenHeader(GE_HIT,object().ID());										//	object().u_EventGen(P,GE_HIT,object().ID());
	THROW2			(tLuaHit.m_tpDraftsman,"Where is hit initiator??!");	//	THROW2			(tLuaHit.m_tpDraftsman,"Where is hit initiator??!");
	HS.whoID  = u16(tLuaHit.m_tpDraftsman->ID());							//	P.w_u16			(u16(tLuaHit.m_tpDraftsman->ID()));
	HS.weaponID = 0;														//	P.w_u16			(0);
	HS.dir = tLuaHit.m_tDirection;											//	P.w_dir			(tLuaHit.m_tDirection);
	HS.power = tLuaHit.m_fPower;											//	P.w_float		(tLuaHit.m_fPower);
	CKinematics		*V = smart_cast<CKinematics*>(object().Visual());		//	CKinematics		*V = smart_cast<CKinematics*>(object().Visual());
	VERIFY			(V);													//	VERIFY			(V);
	if (xr_strlen	(tLuaHit.m_caBoneName))									//	if (xr_strlen	(tLuaHit.m_caBoneName))
		HS.boneID = 		(V->LL_BoneID(tLuaHit.m_caBoneName));			//		P.w_s16		(V->LL_BoneID(tLuaHit.m_caBoneName));
	else																	//	else
		HS.boneID = 		(s16(0));										//		P.w_s16		(s16(0));
	HS.p_in_bone_space = Fvector().set(0,0,0);								//	P.w_vec3		(Fvector().set(0,0,0));
	HS.impulse = tLuaHit.m_fImpulse;										//	P.w_float		(tLuaHit.m_fImpulse);
	HS.hit_type = (ALife::EHitType)(tLuaHit.m_tHitType);					//	P.w_u16			(u16(tLuaHit.m_tHitType));
	HS.Write_Packet(P);						

	object().u_EventSend(P);
}
Beispiel #23
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;
	}

}
Beispiel #25
0
void CBlackGraviArtefact::GraviStrike()
{
	xr_list<s16>		elements_list;
	xr_list<Fvector>	bone_position_list;

	Fvector object_pos					; 
	Fvector strike_dir					;

	rq_storage.r_clear	();

	for(GAME_OBJECT_LIST_it it = m_GameObjectList.begin(); 
						    m_GameObjectList.end() != it;
							++it)
	{
		CPhysicsShellHolder* pGameObject = *it;

		if(pGameObject->Visual()) 
			pGameObject->Center(object_pos); 
		else 
			object_pos.set(pGameObject->Position());

		strike_dir.sub(object_pos, Position()); 
		float distance = strike_dir.magnitude(); 

		float impulse = 100.f*m_fStrikeImpulse * (1.f - (distance/m_fRadius)*
										   (distance/m_fRadius));
						
		if(impulse > .001f) 
		{
//?			BOOL		enabled = getEnabled();
//?			setEnabled	(FALSE);
			impulse		*= CExplosive::ExplosionEffect	(rq_storage,NULL,pGameObject, Position(),m_fRadius);
//?			setEnabled	(enabled);
		}

		float hit_power		;
		CEntityAlive* pEntityAlive = smart_cast<CEntityAlive*>(pGameObject);
		if(pGameObject->m_pPhysicsShell)	hit_power = 0;
		else if(pEntityAlive && pEntityAlive->g_Alive() && 
				pEntityAlive->character_physics_support()->movement()->CharacterExist())
			hit_power = 0;
		else
			hit_power = impulse;

		
		if(impulse > .001f) 
		{
			while(!elements_list.empty()) 
			{
				s16 element = elements_list.front();
				Fvector bone_pos = bone_position_list.front();
				
				NET_Packet		P;
				SHit	HS;
				HS.GenHeader(GE_HIT, pGameObject->ID());	//				u_EventGen		(P,GE_HIT, pGameObject->ID());				
				HS.whoID  =ID();							//				P.w_u16			(ID());
				HS.weaponID = ID();							//				P.w_u16			(ID());
				HS.dir = strike_dir;						//				P.w_dir			(strike_dir);
				HS.power = hit_power;						//				P.w_float		(hit_power);
				HS.boneID = element;						//				P.w_s16			(element);
				HS.p_in_bone_space = bone_pos;				//				P.w_vec3		(bone_pos);
				HS.impulse = impulse;						//				P.w_float		(impulse);
				HS.hit_type = (ALife::eHitTypeWound);		//				P.w_u16			(u16(ALife::eHitTypeWound));
				HS.Write_Packet(P);

				u_EventSend		(P);
				elements_list.pop_front();
				bone_position_list.pop_front();
			}
		}
	}
}
Beispiel #26
0
void CGameObject::OnEvent		(NET_Packet& P, u16 type)
{
	switch (type)
	{
	case GE_HIT:
	case GE_HIT_STATISTIC:
		{
/*
			u16				id,weapon_id;
			Fvector			dir;
			float			power, impulse;
			s16				element;
			Fvector			position_in_bone_space;
			u16				hit_type;
			float			ap = 0.0f;

			P.r_u16			(id);
			P.r_u16			(weapon_id);
			P.r_dir			(dir);
			P.r_float		(power);
			P.r_s16			(element);
			P.r_vec3		(position_in_bone_space);
			P.r_float		(impulse);
			P.r_u16			(hit_type);	//hit type
			if ((ALife::EHitType)hit_type == ALife::eHitTypeFireWound)
			{
				P.r_float	(ap);
			}

			CObject*	Hitter = Level().Objects.net_Find(id);
			CObject*	Weapon = Level().Objects.net_Find(weapon_id);

			SHit	HDS = SHit(power, dir, Hitter, element, position_in_bone_space, impulse, (ALife::EHitType)hit_type, ap);
*/
			SHit	HDS;
			HDS.PACKET_TYPE = type;
			HDS.Read_Packet_Cont(P);
//			Msg("Hit received: %d[%d,%d]", HDS.whoID, HDS.weaponID, HDS.BulletID);
			CObject*	Hitter = Level().Objects.net_Find(HDS.whoID);
			CObject*	Weapon = Level().Objects.net_Find(HDS.weaponID);
			HDS.who		= Hitter;
			if (!HDS.who)
			{
				Msg("! ERROR: hitter object [%d] is NULL on client.", HDS.whoID);
			}
			//-------------------------------------------------------
			switch (HDS.PACKET_TYPE)
			{
			case GE_HIT_STATISTIC:
				{
					if (GameID() != eGameIDSingle)
						Game().m_WeaponUsageStatistic->OnBullet_Check_Request(&HDS);
				}break;
			default:
				{
				}break;
			}
			SetHitInfo(Hitter, Weapon, HDS.bone(), HDS.p_in_bone_space, HDS.dir);
			Hit				(&HDS);
			//---------------------------------------------------------------------------
			if (GameID() != eGameIDSingle)
			{
				Game().m_WeaponUsageStatistic->OnBullet_Check_Result(false);
				game_cl_mp*	mp_game = smart_cast<game_cl_mp*>(&Game());
				if (mp_game->get_reward_generator())
					mp_game->get_reward_generator()->OnBullet_Hit(Hitter, this, Weapon, HDS.boneID);
			}
			//---------------------------------------------------------------------------
		}
		break;
	case GE_DESTROY:
		{
			if ( H_Parent() )
			{
				Msg( "! ERROR (GameObject): GE_DESTROY arrived to object[%d][%s], that has parent[%d][%s], frame[%d]",
					ID(), cNameSect().c_str(),
					H_Parent()->ID(), H_Parent()->cName().c_str(), Device.dwFrame );
				
				// This object will be destroy on call function <H_Parent::Destroy>
				// or it will be call <H_Parent::Reject>  ==>  H_Parent = NULL
				// !!! ___ it is necessary to be check!
				break;
			}
#ifdef MP_LOGGING
			Msg("--- Object: GE_DESTROY of [%d][%s]", ID(), cNameSect().c_str());
#endif // MP_LOGGING

			setDestroy		(TRUE);
//			MakeMeCrow		();
		}
		break;
	}
}
Beispiel #27
0
void			CAI_Stalker::Hit					(SHit* pHDS)
{
//	pHDS->power						*= .1f;

	//хит может меняться в зависимости от ранга (новички получают больше хита, чем ветераны)
	SHit							HDS = *pHDS;
	HDS.power						*= m_fRankImmunity;
	if (m_boneHitProtection && HDS.hit_type == ALife::eHitTypeFireWound){
		float						BoneArmour = m_boneHitProtection->getBoneArmour(HDS.bone());	
		float						NewHitPower = HDS.damage() - BoneArmour;
		if (NewHitPower < HDS.power*m_boneHitProtection->m_fHitFrac) HDS.power = HDS.power*m_boneHitProtection->m_fHitFrac;
		else
			HDS.power				= NewHitPower;

		if (wounded())
			HDS.power				= 1000.f;
	}

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

		if (!already_critically_wounded) {
			const CCoverPoint		*cover = agent_manager().member().member(this).cover();
			if (cover && pHDS->initiator() && (pHDS->initiator()->ID() != ID()) && !fis_zero(pHDS->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*>(pHDS->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() &&
				(pHDS->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*pHDS->damage()/100.f;
				clamp					(power_factor,0.f,1.f);

				CKinematicsAnimated		*tpKinematics = smart_cast<CKinematicsAnimated*>(Visual());
	#ifdef DEBUG
				tpKinematics->LL_GetBoneInstance	(pHDS->bone());
				if (pHDS->bone() >= tpKinematics->LL_BoneCount()) {
					Msg					("tpKinematics has no bone_id %d",pHDS->bone());
					pHDS->_dump			();
				}
	#endif
				int						fx_index = iFloor(tpKinematics->LL_GetBoneInstance(pHDS->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->on_critical_wound_initiator	(this);
					}
				}
			}
		}
	}

	inherited::Hit					(&HDS);
}
void CPolterFlame::update_schedule()
{
	inherited::update_schedule();

	//---------------------------------------------------------------------
	// Update Scanner
	
	if (m_object->g_Alive()) {
		
		// check the start of scanning
		if (!m_state_scanning && !m_object->EnemyMan.get_enemy()) {
			// check radius
			if (Actor()->Position().distance_to(m_object->Position()) < m_scan_radius) {
				// check timing
				if (m_scan_next_time < time()) {
					// start here
					m_state_scanning = true;

					// играть звук
					//m_scan_sound.play_at_pos(m_object, get_head_position(Actor()),sm_2D);
					::Sound->play_at_pos(m_scan_sound, 0, Actor()->Position());

					// постпроцесс
					Actor()->Cameras().AddPPEffector(new CMonsterEffector(m_scan_effector_info, m_scan_effector_time, m_scan_effector_time_attack, m_scan_effector_time_release));
				}
				
			}
		} 
		// check stop of scanning (it currently scans)
		else {
			if (!m_scan_sound._feedback()) {
				// stop here
				m_state_scanning = false;
				
				// count next scan time
				m_scan_next_time = time() + Random.randI(m_scan_delay_min,m_scan_delay_max);
			}
		}
	}
	//---------------------------------------------------------------------


	// check all flames
	for (FLAME_ELEMS_IT it = m_flames.begin();it != m_flames.end();it++) {
		SFlameElement *elem = *it;
	
		// test switches to states
		switch(elem->state) {
		case ePrepare:	
			// check if time_out
			if (elem->time_started + m_time_fire_delay < time()) select_state(elem,eFire);
			break;
		case eFire:		
			if (elem->time_started + m_time_fire_play < time()) select_state(elem,eStop);
			else {
				
				// check if we need test hit to enemy
				if (elem->time_last_hit + m_hit_delay < time()) {
					// test hit
					collide::rq_result rq;
					if (Level().ObjectSpace.RayPick(elem->position, elem->target_dir, m_length, collide::rqtBoth, rq, NULL)) {
						if ((rq.O == elem->target_object) && (rq.range < m_length)) {
							float		hit_value;
							hit_value	= m_hit_value - m_hit_value * rq.range / m_length;

							NET_Packet			P;
							SHit				HS;
							HS.GenHeader		(GE_HIT, elem->target_object->ID());	//					u_EventGen		(P,GE_HIT, element->target_object->ID());
							HS.whoID			= (m_object->ID());						//					P.w_u16			(ID());
							HS.weaponID			= (m_object->ID());						//					P.w_u16			(ID());
							HS.dir				= (elem->target_dir);					//					P.w_dir			(element->target_dir);
							HS.power			= (hit_value);							//					P.w_float		(m_flame_hit_value);
							HS.boneID			= (BI_NONE);							//					P.w_s16			(BI_NONE);
							HS.p_in_bone_space	= (Fvector().set(0.f,0.f,0.f));			//					P.w_vec3		(Fvector().set(0.f,0.f,0.f));
							HS.impulse			= (0.f);								//					P.w_float		(0.f);
							HS.hit_type			= (ALife::eHitTypeBurn);				//					P.w_u16			(u16(ALife::eHitTypeBurn));

							HS.Write_Packet			(P);
							m_object->u_EventSend	(P);

							elem->time_last_hit	= time();
						}
					}
				}
			}
			break;
		case eStop:
			xr_delete(*it);
			break;
		}
	}

	// remove all flames in state stop
	
	// удалить все элементы, выполнение которых закончено
	m_flames.erase	(
		std::remove_if(
			m_flames.begin(),
			m_flames.end(),
			remove_predicate()
		),
		m_flames.end()
	);
	
	// check if we can create another flame
	if (m_object->g_Alive() && m_object->EnemyMan.get_enemy() && (m_flames.size() < m_count)) {
		// check aura radius and accessibility
		float dist = m_object->EnemyMan.get_enemy()->Position().distance_to(m_object->Position());
		if ((dist < m_pmt_aura_radius) && m_object->control().path_builder().accessible(m_object->EnemyMan.get_enemy()->Position())) {
			// check timing
			if (m_time_flame_started + m_delay < time()) {
				create_flame(m_object->EnemyMan.get_enemy());
			}
		}
	}

	

}
Beispiel #29
0
void CBaseMonster::HitEntity(const CEntity *pEntity, float fDamage, float impulse, Fvector &dir, ALife::EHitType hit_type, bool draw_hit_marks)
{
	if (!g_Alive()) return;
	if (!pEntity || pEntity->getDestroy()) return;

	if (!EnemyMan.get_enemy()) return;

	if (EnemyMan.get_enemy() == pEntity) {
		Fvector position_in_bone_space;
		position_in_bone_space.set(0.f,0.f,0.f);

		// перевод из локальных координат в мировые вектора направления импульса
		Fvector hit_dir;
		XFORM().transform_dir	(hit_dir,dir);
		hit_dir.normalize		();

		CEntity		*pEntityNC	= const_cast<CEntity*>(pEntity);
		VERIFY		(pEntityNC);
		
		NET_Packet	l_P;
		SHit		HS;
		HS.GenHeader(GE_HIT, pEntityNC->ID());													//		u_EventGen	(l_P,GE_HIT, pEntityNC->ID());
		HS.whoID			= (ID());															//		l_P.w_u16	(ID());
		HS.weaponID			= (ID());															//		l_P.w_u16	(ID());
		HS.dir				= (hit_dir);														//		l_P.w_dir	(hit_dir);
		HS.power			= (fDamage);														//		l_P.w_float	(fDamage);
		HS.boneID			= (smart_cast<IKinematics*>(pEntityNC->Visual())->LL_GetBoneRoot());//		l_P.w_s16	(smart_cast<IKinematics*>(pEntityNC->Visual())->LL_GetBoneRoot());
		HS.p_in_bone_space	= (position_in_bone_space);											//		l_P.w_vec3	(position_in_bone_space);
		HS.impulse			= (impulse);														//		l_P.w_float	(impulse);
		HS.hit_type			= hit_type;															//		l_P.w_u16	( u16(ALife::eHitTypeWound) );
		HS.Write_Packet(l_P);
		u_EventSend	(l_P);
		
		if (pEntityNC == Actor() && draw_hit_marks) {
			START_PROFILE("BaseMonster/Animation/HitEntity");

			SDrawStaticStruct* s = CurrentGameUI()->AddCustomStatic("monster_claws", false);
			
			float h1,p1;
			Device.vCameraDirection.getHP	(h1,p1);
			Fvector hd				= hit_dir;
			hd.mul					(-1);
			float d = -h1 + hd.getH	();
			s->wnd()->SetHeading	(d);
			Fvector2 wnd_pos = s->wnd()->GetWndPos();
			wnd_pos.y	+= 400.0f*_cos(d);
			wnd_pos.x	+= 500.0f*_sin(d);
			s->wnd()->SetWndPos(wnd_pos);

			STOP_PROFILE;

			//SetAttackEffector			();
			
			float time_to_lock		= fDamage * MAX_LOCK_TIME;
			clamp					(time_to_lock, 0.f, MAX_LOCK_TIME);
			Actor()->lock_accel_for	(int(time_to_lock * 1000));

			//////////////////////////////////////////////////////////////////////////
			//
			//////////////////////////////////////////////////////////////////////////
			
			CEffectorCam* ce = Actor()->Cameras().GetCamEffector((ECamEffectorType)effBigMonsterHit);
			if(!ce)
			{
				const shared_str&	eff_sect = pSettings->r_string(cNameSect(), "actor_hit_effect");	
				if(eff_sect.c_str())
				{
					int id						= -1;
					Fvector						cam_pos,cam_dir,cam_norm;
					Actor()->cam_Active()->Get	(cam_pos,cam_dir,cam_norm);
					cam_dir.normalize_safe		();
					dir.normalize_safe			();

					float ang_diff				= angle_difference	(cam_dir.getH(), dir.getH());
					Fvector						cp;
					cp.crossproduct				(cam_dir,dir);
					bool bUp					=(cp.y>0.0f);

					Fvector cross;
					cross.crossproduct			(cam_dir, dir);
					VERIFY						(ang_diff>=0.0f && ang_diff<=PI);

					float _s1 = PI_DIV_8;
					float _s2 = _s1+PI_DIV_4;
					float _s3 = _s2+PI_DIV_4;
					float _s4 = _s3+PI_DIV_4;

					if(ang_diff<=_s1){
						id = 2;
					}else {
						if(ang_diff>_s1 && ang_diff<=_s2){
							id = (bUp)?5:7;
						}else
							if(ang_diff>_s2 && ang_diff<=_s3){
								id = (bUp)?3:1;
							}else
								if(ang_diff>_s3 && ang_diff<=_s4){
									id = (bUp)?4:6;
								}else
									if(ang_diff>_s4){
										id = 0;
									}else{
										VERIFY(0);
									}
					}
					
					string64				sect_name;

					xr_sprintf					(sect_name,"%s_%d",eff_sect.c_str(), id);
					AddEffector				(Actor(), effBigMonsterHit, sect_name, fDamage);
				}
			}
			//////////////////////////////////////////////////////////////////////////
			

		}

		Morale.on_attack_success();
		
		m_time_last_attack_success	= Device.dwTimeGlobal;
	}
}
Beispiel #30
0
void	CActor::Hit							(SHit* pHDS)
{
	pHDS->aim_bullet = false;

	SHit HDS = *pHDS;
	if( HDS.hit_type<ALife::eHitTypeBurn || HDS.hit_type >= ALife::eHitTypeMax )
	{
		string256	err;
		sprintf		(err, "Unknown/unregistered hit type [%d]", HDS.hit_type);
		R_ASSERT2	(0, err );
	
	}
#ifdef DEBUG
if(ph_dbg_draw_mask.test(phDbgCharacterControl))
{
	DBG_OpenCashedDraw();
	Fvector to;to.add(Position(),Fvector().mul(HDS.dir,HDS.phys_impulse()));
	DBG_DrawLine(Position(),to,D3DCOLOR_XRGB(124,124,0));
	DBG_ClosedCashedDraw(500);
}
#endif
	bool bPlaySound = true;
	if (!g_Alive()) bPlaySound = false;

	if (!IsGameTypeSingle() && !g_pGamePersistent->bDedicatedServer)
	{
		game_PlayerState* ps = Game().GetPlayerByGameID(ID());
		if (ps && ps->testFlag(GAME_PLAYER_FLAG_INVINCIBLE))
		{
			bPlaySound = false;
			if (Device.dwFrame != last_hit_frame &&
				HDS.bone() != BI_NONE)
			{		
				// вычислить позицию и направленность партикла
				Fmatrix pos; 

				CParticlesPlayer::MakeXFORM(this,HDS.bone(),HDS.dir,HDS.p_in_bone_space,pos);

				// установить particles
				CParticlesObject* ps = NULL;

				if (eacFirstEye == cam_active && this == Level().CurrentEntity())
					ps = CParticlesObject::Create(invincibility_fire_shield_1st,TRUE);
				else
					ps = CParticlesObject::Create(invincibility_fire_shield_3rd,TRUE);

				ps->UpdateParent(pos,Fvector().set(0.f,0.f,0.f));
				GamePersistent().ps_needtoplay.push_back(ps);
			};
		};
		 

		last_hit_frame = Device.dwFrame;
	};

	if(	!g_pGamePersistent->bDedicatedServer	&& 
		!sndHit[HDS.hit_type].empty()			&& 
		(ALife::eHitTypeTelepatic != HDS.hit_type))
	{
		ref_sound& S = sndHit[HDS.hit_type][Random.randI(sndHit[HDS.hit_type].size())];
		bool b_snd_hit_playing = sndHit[HDS.hit_type].end() != std::find_if(sndHit[HDS.hit_type].begin(), sndHit[HDS.hit_type].end(), playing_pred());

		if(ALife::eHitTypeExplosion == HDS.hit_type)
		{
			if (this == Level().CurrentControlEntity())
			{
				S.set_volume(10.0f);
				if(!m_sndShockEffector){
					m_sndShockEffector = xr_new<SndShockEffector>();
					m_sndShockEffector->Start(this, float(S._handle()->length_ms()), HDS.damage() );
				}
			}
			else
				bPlaySound = false;
		}
		if (bPlaySound && !b_snd_hit_playing) 
		{
			Fvector point		= Position();
			point.y				+= CameraHeight();
			S.play_at_pos		(this, point);
		};
	}

	
	//slow actor, only when he gets hit
	if(HDS.hit_type == ALife::eHitTypeWound || HDS.hit_type == ALife::eHitTypeStrike)
	{
		hit_slowmo				= HDS.damage();
		clamp					(hit_slowmo,0.0f,1.f);
	}
	else
		hit_slowmo = 0.f;
	//---------------------------------------------------------------
	if (Level().CurrentViewEntity() == this && !g_pGamePersistent->bDedicatedServer && HDS.hit_type == ALife::eHitTypeFireWound)
	{
		CObject* pLastHitter = Level().Objects.net_Find(m_iLastHitterID);
		CObject* pLastHittingWeapon = Level().Objects.net_Find(m_iLastHittingWeaponID);
		HitSector(pLastHitter, pLastHittingWeapon);
	};

	if ((mstate_real&mcSprint) && Level().CurrentControlEntity() == this && 
		HDS.hit_type != ALife::eHitTypeTelepatic &&
		HDS.hit_type != ALife::eHitTypeRadiation 
		)
	{
//		mstate_real	&=~mcSprint;
		mstate_wishful	&=~mcSprint;
	};
	if(!g_pGamePersistent->bDedicatedServer)
	{
		HitMark			(HDS.damage(), HDS.dir, HDS.who, HDS.bone(), HDS.p_in_bone_space, HDS.impulse, HDS.hit_type);
	}

	switch (GameID())
	{
	case GAME_SINGLE:		
		{
			float hit_power	= HitArtefactsOnBelt(HDS.damage(), HDS.hit_type);

			if (GodMode())//psActorFlags.test(AF_GODMODE))
			{
				HDS.power = 0.0f;
//				inherited::Hit(0.f,dir,who,element,position_in_bone_space,impulse, hit_type);
				inherited::Hit(&HDS);
				return;
			}
			else 
			{
				//inherited::Hit		(hit_power,dir,who,element,position_in_bone_space, impulse, hit_type);
				HDS.power = hit_power;
				inherited::Hit(&HDS);
			};
		}
		break;
	default:
		{
			m_bWasBackStabbed = false;
			if (HDS.hit_type == ALife::eHitTypeWound_2 && Check_for_BackStab_Bone(HDS.bone()))
			{
				// convert impulse into local coordinate system
				Fmatrix					mInvXForm;
				mInvXForm.invert		(XFORM());
				Fvector					vLocalDir;
				mInvXForm.transform_dir	(vLocalDir,HDS.dir);
				vLocalDir.invert		();

				Fvector a	= {0,0,1};
				float res = a.dotproduct(vLocalDir);
				if (res < -0.707)
				{
					game_PlayerState* ps = Game().GetPlayerByGameID(ID());
					if (!ps || !ps->testFlag(GAME_PLAYER_FLAG_INVINCIBLE))						
						m_bWasBackStabbed = true;
				}
			};
			
			float hit_power = 0;

			if (m_bWasBackStabbed) hit_power = 100000;
			else hit_power	= HitArtefactsOnBelt(HDS.damage(), HDS.hit_type);

			HDS.power = hit_power;
			inherited::Hit (&HDS);
			//inherited::Hit	(hit_power,dir,who,element,position_in_bone_space, impulse, hit_type, 0.0f);
		}		
		break;
	}
}