Esempio n. 1
0
void CExplosive::OnAfterExplosion()
{
	if(m_pExpParticle){
		m_pExpParticle->Stop();
		CParticlesObject::Destroy(m_pExpParticle);
		m_pExpParticle = NULL;
	}
	//ликвидировать сам объект 
	if (cast_game_object()->Local()) cast_game_object()->DestroyObject();
}
Esempio n. 2
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
}
Esempio n. 3
0
void CExplosive::OnAfterExplosion()
{
	if(m_pExpParticle){
		m_pExpParticle->Stop();
		CParticlesObject::Destroy(m_pExpParticle);
		m_pExpParticle = NULL;
	}
	//ликвидировать сам объект 
	if (cast_game_object()->Local()) cast_game_object()->DestroyObject();
	
//	NET_Packet			P;
//	cast_game_object()->u_EventGen			(P,GE_DESTROY,cast_game_object()->ID());
//	//		Msg					("ge_destroy: [%d] - %s",ID(),*cName());
//	if (cast_game_object()->Local()) cast_game_object()->u_EventSend			(P);
}
Esempio n. 4
0
void CExplosive::ActivateExplosionBox(const Fvector &size,Fvector &in_out_pos)
{
	CPhysicsShellHolder		*self_obj=smart_cast<CPhysicsShellHolder*>(cast_game_object());
	CPhysicsShell* self_shell=self_obj->PPhysicsShell();
	if(self_shell&&self_shell->isActive())self_shell->DisableCollision();
	ActivateShapeExplosive( self_obj, size, m_vExplodeSize, in_out_pos );
	if(self_shell&&self_shell->isActive())self_shell->EnableCollision();
}
Esempio n. 5
0
void CExplosive::Load(CInifile *ini,LPCSTR section)
{
	m_fBlastHit			= ini->r_float(section,"blast");
	m_fBlastRadius		= ini->r_float(section,"blast_r");
	m_fBlastHitImpulse	= ini->r_float(section,"blast_impulse");

	m_iFragsNum			= ini->r_s32(section,"frags");
	m_fFragsRadius		= ini->r_float(section,"frags_r");
	m_fFragHit			= ini->r_float(section,"frag_hit");
	m_fFragHitImpulse	= ini->r_float(section,"frag_hit_impulse");

	m_eHitTypeBlast		= ALife::g_tfString2HitType(ini->r_string(section, "hit_type_blast"));
	m_eHitTypeFrag		= ALife::g_tfString2HitType(ini->r_string(section, "hit_type_frag"));

	m_fUpThrowFactor	= ini->r_float(section,"up_throw_factor");


	fWallmarkSize		= ini->r_float(section,"wm_size");
	R_ASSERT			(fWallmarkSize>0);

	m_sExplodeParticles = ini->r_string(section,"explode_particles");

	sscanf				(ini->r_string(section,"light_color"), "%f,%f,%f", &m_LightColor.r, &m_LightColor.g, &m_LightColor.b);
	m_fLightRange		= ini->r_float(section,"light_range");
	m_fLightTime		= ini->r_float(section,"light_time");

	//трассы для разлета осколков
	m_fFragmentSpeed			= ini->r_float	(section,"fragment_speed"				);

	LPCSTR	snd_name		= ini->r_string(section,"snd_explode");
	sndExplode.create		(snd_name, st_Effect,m_eSoundExplode);

	m_fExplodeDurationMax	= ini->r_float(section, "explode_duration");

	effector.effect_sect_name= ini->r_string("explode_effector","effect_sect_name");
//	if( ini->line_exist(section,"wallmark_section") )
//	{
		m_wallmark_manager.m_owner = cast_game_object();
//		m_wallmark_manager.Load(pSettings,ini->r_string(section,"wallmark_section"));
//	}

	m_bHideInExplosion = TRUE;
	if (ini->line_exist(section, "hide_in_explosion"))
	{
		m_bHideInExplosion = ini->r_bool(section, "hide_in_explosion");
		m_fExplodeHideDurationMax = 0;
		if (ini->line_exist(section, "explode_hide_duration"))
		{
			m_fExplodeHideDurationMax = ini->r_float(section, "explode_hide_duration");
		}
	}

	m_bDynamicParticles	 = FALSE;
	if (ini->line_exist(section, "dynamic_explosion_particles"))
		m_bDynamicParticles = ini->r_bool(section, "dynamic_explosion_particles");
}
Esempio n. 6
0
void CExplosive::GenExplodeEvent (const Fvector& pos, const Fvector& normal)
{
	if (OnClient() || cast_game_object()->Remote()) return;

//	if( m_bExplodeEventSent ) 
//		return;
	VERIFY(!m_explosion_flags.test(flExplodEventSent));//!m_bExplodeEventSent
	VERIFY(0xffff != Initiator());

	NET_Packet		P;
	cast_game_object()->u_EventGen		(P,GE_GRENADE_EXPLODE,cast_game_object()->ID());	
	P.w_u16			(Initiator());
	P.w_vec3		(pos);
	P.w_vec3		(normal);
	cast_game_object()->u_EventSend		(P);

	//m_bExplodeEventSent = true;
	m_explosion_flags.set(flExplodEventSent,TRUE);
}
Esempio n. 7
0
void CExplosive::UpdateExplosionParticles ()
{
	if (!m_bDynamicParticles || m_pExpParticle == NULL || !m_pExpParticle->IsPlaying()) return;
	CGameObject	*GO=cast_game_object();
	if (!GO) return;

	Fmatrix ParticleMatrix = m_pExpParticle->XFORM();	
	Fvector Vel;
	Vel.sub(GO->Position(), ParticleMatrix.c);
	ParticleMatrix.c.set(GO->Position());
	m_pExpParticle->UpdateParent(ParticleMatrix, Vel);
}
Esempio n. 8
0
void CExplosive::FindNormal(Fvector& normal)
{
	collide::rq_result RQ;

	Fvector pos, dir;
	dir.set(0,-1.f,0);
	cast_game_object()->Center(pos);

	BOOL result = Level().ObjectSpace.RayPick(pos, dir, cast_game_object()->Radius(), 
											 collide::rqtBoth, RQ, NULL);
	if(!result || RQ.O){
		normal.set(0,1,0);
	//если лежим на статике
	//найти треугольник и вычислить нормаль по нему
	}else
	{
		Fvector*	pVerts	= Level().ObjectSpace.GetStaticVerts();
		CDB::TRI*	pTri	= Level().ObjectSpace.GetStaticTris() + RQ.element;
		normal.mknormal	(pVerts[pTri->verts[0]],pVerts[pTri->verts[1]],pVerts[pTri->verts[2]]);
	}
}
Esempio n. 9
0
void CExplosive::UpdateCL() 
{
	//VERIFY(!this->getDestroy());
	VERIFY(!ph_world->Processing());
	if(!m_explosion_flags.test(flExploding)) return;// !m_bExploding
	if(m_explosion_flags.test(flExploded))
	{
		CGameObject* go=cast_game_object();
		go->processing_deactivate();
		m_explosion_flags.set(flExploding,FALSE);//m_bExploding = false;
		OnAfterExplosion();
		return;
	}
	//время вышло, убираем объект взрывчатки
	if(m_fExplodeDuration < 0.f&&m_blasted_objects.empty()) 
	{
		m_explosion_flags.set(flExploded,TRUE);
		
		
		StopLight();
		

//		Msg("---------CExplosive OnAfterExplosion [%d] frame[%d]",cast_game_object()->ID(), Device.dwFrame);

	} 
	else
	{		
		m_fExplodeDuration -= Device.fTimeDelta;
		if (!m_bHideInExplosion && !m_bAlreadyHidden)
		{
			if (m_fExplodeHideDurationMax <= (m_fExplodeDurationMax - m_fExplodeDuration))
			{
				HideExplosive();
			}
		}
		UpdateExplosionPos();
		UpdateExplosionParticles();
		ExplodeWaveProcess();
		//обновить подсветку взрыва
		if(m_pLight && m_pLight->get_active() && m_fLightTime>0)
		{
			if(m_fExplodeDuration > (m_fExplodeDurationMax - m_fLightTime))
			{
				float scale = (m_fExplodeDuration - (m_fExplodeDurationMax - m_fLightTime))/m_fLightTime;
				m_pLight->set_color(m_LightColor.r*scale, m_LightColor.g*scale, m_LightColor.b*scale);
				m_pLight->set_range(m_fLightRange*scale);
			} 
			else
				StopLight();
		}		
	}
}
Esempio n. 10
0
CCustomMonster::CCustomMonster() :
	// this is non-polymorphic call of the virtual function cast_entity_alive
	// just to remove warning C4355 if we use this instead
	Feel::Vision				( cast_game_object() ) 
{
	m_sound_user_data_visitor	= 0;
	m_memory_manager			= 0;
	m_movement_manager			= 0;
	m_sound_player				= 0;
	m_already_dead				= false;
	m_invulnerable				= false;
	m_moving_object				= 0;
}
Esempio n. 11
0
void CExplosive::HideExplosive()
{
	CGameObject	*GO=cast_game_object();
	GO->setVisible(FALSE);
	GO->setEnabled(FALSE);
	CPhysicsShell* phshell=(smart_cast<CPhysicsShellHolder*>(GO))->PPhysicsShell();
	if(phshell)
	{
		phshell->Disable();
		phshell->DisableCollision();
	}
	m_bAlreadyHidden = true;
};
Esempio n. 12
0
void CExplosive::ActivateExplosionBox(const Fvector &size,Fvector &in_out_pos)
{
	CPhysicsShellHolder		*self_obj=smart_cast<CPhysicsShellHolder*>(cast_game_object());
	CPhysicsShell* self_shell=self_obj->PPhysicsShell();
	if(self_shell&&self_shell->isActive())self_shell->DisableCollision();
	CPHActivationShape activation_shape;//Fvector start_box;m_PhysicMovementControl.Box().getsize(start_box);
	activation_shape.Create(in_out_pos,size,self_obj);
	dBodySetGravityMode(activation_shape.ODEBody(),0);
	activation_shape.Activate(size,1,1.f,M_PI/8.f);
	in_out_pos.set(activation_shape.Position());
	activation_shape.Size(m_vExplodeSize);
	activation_shape.Destroy();
	if(self_shell&&self_shell->isActive())self_shell->EnableCollision();
}
Esempio n. 13
0
u16	CExplosive::Initiator()
{
	u16 initiator=CurrentParentID();
	if(initiator==u16(-1))initiator=cast_game_object()->ID();
	return initiator;
}
Esempio n. 14
0
void CExplosive::GetExplVelocity(Fvector &v)
{
	smart_cast<CPhysicsShellHolder*>(cast_game_object())->PHGetLinearVell(v);
}
Esempio n. 15
0
void CExplosive::Explode()
{
	VERIFY(0xffff != Initiator());
	VERIFY(m_explosion_flags.test(flReadyToExplode));//m_bReadyToExplode
	VERIFY(!ph_world->Processing());
	//m_bExploding = true;
	m_explosion_flags.set(flExploding,TRUE);
	cast_game_object()->processing_activate();

	Fvector& pos = m_vExplodePos;
	Fvector& dir = m_vExplodeDir;
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
		DBG_OpenCashedDraw();
		DBG_DrawPoint(pos,0.3f,D3DCOLOR_XRGB(255,0,0));
	}
#endif
//	Msg("---------CExplosive Explode [%d] frame[%d]",cast_game_object()->ID(), Device.dwFrame);
	OnBeforeExplosion();
	//играем звук взрыва
	Sound->play_at_pos(sndExplode, 0, pos, false);
	
	//показываем эффекты

	m_wallmark_manager.PlaceWallmarks		(pos);

	Fvector									vel;
	smart_cast<CPhysicsShellHolder*>(cast_game_object())->PHGetLinearVell(vel);

	Fmatrix explode_matrix;
	explode_matrix.identity();
	explode_matrix.j.set(dir);
	Fvector::generate_orthonormal_basis(explode_matrix.j, explode_matrix.i, explode_matrix.k);
	explode_matrix.c.set(pos);

	CParticlesObject* pStaticPG; 
	pStaticPG = CParticlesObject::Create(*m_sExplodeParticles,!m_bDynamicParticles); 
	if (m_bDynamicParticles) m_pExpParticle = pStaticPG;
	pStaticPG->UpdateParent(explode_matrix,vel);
	pStaticPG->Play();

	//включаем подсветку от взрыва
	StartLight();

	//trace frags
	Fvector frag_dir; 
	
	//////////////////////////////
	//осколки
	//////////////////////////////
	//-------------------------------------
	bool SendHits = false;
	if (OnServer()) SendHits = true;
	else SendHits = false;


	for(int i = 0; i < m_iFragsNum; ++i){
		frag_dir.random_dir	();
		frag_dir.normalize	();
		
		CCartridge cartridge;
		cartridge.m_kDist					= 1.f;
		cartridge.m_kHit					= 1.f;
		cartridge.m_kImpulse				= 1.f;
		cartridge.m_kPierce					= 1.f;
		cartridge.fWallmarkSize				= fWallmarkSize;
		cartridge.bullet_material_idx		= GMLib.GetMaterialIdx(WEAPON_MATERIAL_NAME);
		cartridge.m_flags.set				(CCartridge::cfTracer,FALSE);

		Level().BulletManager().AddBullet(	pos, frag_dir, m_fFragmentSpeed,
											m_fFragHit, m_fFragHitImpulse, Initiator(),
											cast_game_object()->ID(), m_eHitTypeFrag, m_fFragsRadius, 
											cartridge, SendHits );
	}	

	if (cast_game_object()->Remote()) return;
	
	/////////////////////////////////
	//взрывная волна
	////////////////////////////////
	//---------------------------------------------------------------------
	xr_vector<ISpatial*>	ISpatialResult;
	g_SpatialSpace->q_sphere(ISpatialResult,0,STYPE_COLLIDEABLE,pos,m_fBlastRadius);

	m_blasted_objects.clear	();
	for (u32 o_it=0; o_it<ISpatialResult.size(); o_it++)
	{
		ISpatial*		spatial	= ISpatialResult[o_it];
		//		feel_touch_new(spatial->dcast_CObject());

		CPhysicsShellHolder	*pGameObject = smart_cast<CPhysicsShellHolder*>(spatial->dcast_CObject());
		if(pGameObject && cast_game_object()->ID() != pGameObject->ID()) 
			m_blasted_objects.push_back(pGameObject);
	}

	GetExplosionBox(m_vExplodeSize);
START_PROFILE("explosive/activate explosion box")
	ActivateExplosionBox(m_vExplodeSize,m_vExplodePos);
STOP_PROFILE
	//---------------------------------------------------------------------
#ifdef DEBUG
	if(ph_dbg_draw_mask.test(phDbgDrawExplosions))
	{
		DBG_ClosedCashedDraw(100000);
		
	}
#endif
	//////////////////////////////////////////////////////////////////////////
	// Explode Effector	//////////////
	CGameObject* GO = smart_cast<CGameObject*>(Level().CurrentEntity());
	CActor* pActor = smart_cast<CActor*>(GO);
	if(pActor)
	{
		float dist_to_actor = pActor->Position().distance_to(pos);
		float max_dist		= EFFECTOR_RADIUS;
		if (dist_to_actor < max_dist)
			AddEffector	(pActor, effExplodeHit, effector.effect_sect_name, (max_dist - dist_to_actor) / max_dist );
	}
}