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);
}
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);
}
Beispiel #3
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
}
Beispiel #4
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;
	}
}
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);
}
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);
}
Beispiel #7
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);
			}
		}
	}
}
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 #9
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 #10
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);
}
Beispiel #11
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 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 #13
0
void CActorCondition::AffectDamage_InjuriousMaterialAndMonstersInfluence()
{
	float one = 0.1f;
	float tg  = Device.fTimeGlobal;
	if ( m_f_time_affected + one > tg )
	{
		return;
	}

	clamp( m_f_time_affected, tg - (one * 3), tg );

	float psy_influence					=	0;
	float fire_influence				=	0;
	float radiation_influence			=	GetInjuriousMaterialDamage(); // Get Radiation from Material

	// Add Radiation and Psy Level from Monsters
	CPda* const pda						=	m_object->GetPDA();

	if ( pda )
	{
		typedef xr_vector<CObject*>				monsters;

		for ( monsters::const_iterator	it	=	pda->feel_touch.begin();
										it	!=	pda->feel_touch.end();
										++it )
		{
			CBaseMonster* const	monster		=	smart_cast<CBaseMonster*>(*it);
			if ( !monster || !monster->g_Alive() ) continue;

			psy_influence					+=	monster->get_psy_influence();
			radiation_influence				+=	monster->get_radiation_influence();
			fire_influence					+=	monster->get_fire_influence();
		}
	}

	struct 
	{
		ALife::EHitType	type;
		float			value;

	} hits[]		=	{	{ ALife::eHitTypeRadiation, radiation_influence	*	one },
							{ ALife::eHitTypeTelepatic, psy_influence		*	one }, 
							{ ALife::eHitTypeBurn,		fire_influence		*	one }	};

 	NET_Packet	np;

	while ( m_f_time_affected + one < tg )
	{
		m_f_time_affected			+=	one;

		for ( int i=0; i<sizeof(hits)/sizeof(hits[0]); ++i )
		{
			float			damage	=	hits[i].value;
			ALife::EHitType	type	=	hits[i].type;

			if ( damage > EPS )
			{
				SHit HDS = SHit(damage, 
//.								0.0f, 
								Fvector().set(0,1,0), 
								NULL, 
								BI_NONE, 
								Fvector().set(0,0,0), 
								0.0f, 
								type, 
								0.0f, 
								false);

				HDS.GenHeader(GE_HIT, m_object->ID());
				HDS.Write_Packet( np );
				CGameObject::u_EventSend( np );
			}

		} // for

	}//while
}
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 #15
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 #16
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 #17
0
void CPseudoGigant::on_threaten_execute()
{
	// разбросить объекты
	m_nearest.clear_not_free		();
	Level().ObjectSpace.GetNearest	(m_nearest,Position(), 15.f, NULL); 
	for (u32 i=0;i<m_nearest.size();i++) {
		CPhysicsShellHolder  *obj = smart_cast<CPhysicsShellHolder *>(m_nearest[i]);
		if (!obj || !obj->m_pPhysicsShell) continue;

		Fvector dir;
		Fvector pos;
		pos.set(obj->Position());
		pos.y += 2.f;
		dir.sub(pos, Position());
		dir.normalize();
		obj->m_pPhysicsShell->applyImpulse(dir,20 * obj->m_pPhysicsShell->getMass());
	}

	// играть звук
	Fvector		pos;
	pos.set		(Position());
	pos.y		+= 0.1f;
	m_sound_threaten_hit.play_at_pos(this,pos);

	// играть партиклы
	PlayParticles(m_kick_particles, pos, Direction());
	
	CActor *pA = const_cast<CActor *>(smart_cast<const CActor *>(EnemyMan.get_enemy()));
	if (!pA) return;
	if ((pA->MovingState() & ACTOR_DEFS::mcJump) != 0) return;

	float dist_to_enemy = pA->Position().distance_to(Position());
	float			hit_value;
	hit_value		= m_kick_damage - m_kick_damage * dist_to_enemy / m_threaten_dist_max;
	clamp			(hit_value,0.f,1.f);

	// запустить эффектор
	Actor()->Cameras().AddCamEffector(xr_new<CMonsterEffectorHit>(m_threaten_effector.ce_time,m_threaten_effector.ce_amplitude * hit_value,m_threaten_effector.ce_period_number,m_threaten_effector.ce_power * hit_value));
	Actor()->Cameras().AddPPEffector(xr_new<CMonsterEffector>(m_threaten_effector.ppi, m_threaten_effector.time, m_threaten_effector.time_attack, m_threaten_effector.time_release, hit_value));

	// развернуть камеру
	if (pA->cam_Active()) {
		pA->cam_Active()->Move(Random.randI(2) ? kRIGHT : kLEFT, Random.randF(0.3f * hit_value)); 
		pA->cam_Active()->Move(Random.randI(2) ? kUP	: kDOWN, Random.randF(0.3f * hit_value)); 
	}

	Actor()->lock_accel_for	(m_time_kick_actor_slow_down);
	
	// Нанести хит
	NET_Packet	l_P;
	SHit		HS;

	HS.GenHeader		(GE_HIT, pA->ID());														//	u_EventGen	(l_P,GE_HIT, pA->ID());
	HS.whoID			= (ID());														//	l_P.w_u16	(ID());
	HS.weaponID			= (ID());														//	l_P.w_u16	(ID());
	HS.dir				= (Fvector().set(0.f,1.f,0.f));									//	l_P.w_dir	(Fvector().set(0.f,1.f,0.f));
	HS.power			= (hit_value);													//	l_P.w_float	(m_kick_damage);
	HS.boneID			= (smart_cast<IKinematics*>(pA->Visual())->LL_GetBoneRoot());	//	l_P.w_s16	(smart_cast<IKinematics*>(pA->Visual())->LL_GetBoneRoot());
	HS.p_in_bone_space	= (Fvector().set(0.f,0.f,0.f));									//	l_P.w_vec3	(Fvector().set(0.f,0.f,0.f));
	HS.impulse			= (80 * pA->character_physics_support()->movement()->GetMass());						//	l_P.w_float	(20 * pA->movement_control()->GetMass());
	HS.hit_type			= ( ALife::eHitTypeStrike);										//	l_P.w_u16	( u16(ALife::eHitTypeWound) );
	HS.Write_Packet		(l_P);
	u_EventSend			(l_P);	
}