Esempio n. 1
0
	void	Vision::feel_vision_query	(Fmatrix& mFull, Fvector& P)
	{
		CFrustum								Frustum		;
		Frustum.CreateFromMatrix				(mFull,FRUSTUM_P_LRTB|FRUSTUM_P_FAR);

		// Traverse object database
		r_spatial.clear_not_free				();
		g_SpatialSpace->q_frustum
			(
			r_spatial,
			0,
			STYPE_VISIBLEFORAI,
			Frustum
			);

		// Determine visibility for dynamic part of scene
		seen.clear_and_reserve					()	;
		for (u32 o_it=0; o_it<r_spatial.size(); o_it++)
		{
			ISpatial*	spatial								= r_spatial					[o_it];
			CObject*	object								= spatial->dcast_CObject	();
			if (object && feel_vision_isRelevant(object))	seen.push_back				(object);
		}
		if (seen.size()>1) 
		{
			std::sort							(seen.begin(),seen.end());
			xr_vector<CObject*>::iterator end	= std::unique	(seen.begin(),seen.end());
			if (end!=seen.end()) seen.erase		(end,seen.end());
		}
	}
Esempio n. 2
0
void	CActor::Check_for_AutoPickUp()
{
	// mp only
	if (!psActorFlags.test(AF_AUTOPICKUP))		return;
	if (IsGameTypeSingle())						return;
	if (Level().CurrentControlEntity() != this) return;
	if (!g_Alive())								return;

	Fvector bc; 
	bc.add				(Position(), m_AutoPickUp_AABB_Offset);
	Fbox APU_Box;
	APU_Box.set			(Fvector().sub(bc, m_AutoPickUp_AABB), Fvector().add(bc, m_AutoPickUp_AABB));

	xr_vector<ISpatial*>	ISpatialResult;
	g_SpatialSpace->q_box   (ISpatialResult, 0, STYPE_COLLIDEABLE, bc, m_AutoPickUp_AABB);

	// Determine visibility for dynamic part of scene
	for (u32 o_it=0; o_it<ISpatialResult.size(); o_it++)
	{
		ISpatial*		spatial	= ISpatialResult[o_it];
		CInventoryItem*	pIItem	= smart_cast<CInventoryItem*> (spatial->dcast_CObject());

		if (0 == pIItem)														continue;
		if (!pIItem->CanTake())													continue;
		if (Level().m_feel_deny.is_object_denied(spatial->dcast_CObject()) )	continue;


		CGrenade*	pGrenade	= smart_cast<CGrenade*> (pIItem);
		if (pGrenade) continue;

		if (APU_Box.Pick(pIItem->object().Position(), pIItem->object().Position()))
		{
			if (GameID() == eGameIDDeathmatch || GameID() == eGameIDTeamDeathmatch)
			{
				if (pIItem->BaseSlot() == INV_SLOT_2 || pIItem->BaseSlot() == INV_SLOT_3 )
				{
					if (inventory().ItemFromSlot(pIItem->BaseSlot()))
						continue;
				}
			}			
			
			Game().SendPickUpEvent(ID(), pIItem->object().ID());
		}		
	}
}
Esempio n. 3
0
BOOL CObjectSpace::_RayPick	( const Fvector &start, const Fvector &dir, float range, rq_target tgt, rq_result& R, CObject* ignore_object)
{
	r_temp.r_clear			();
	R.O		= 0; R.range = range; R.element = -1;
	// static test
	if (tgt&rqtStatic){ 
		xrc.ray_options		(CDB::OPT_ONLYNEAREST | CDB::OPT_CULL);
		xrc.ray_query		(&Static,start,dir,range);
		if (xrc.r_count())  R.set_if_less(xrc.r_begin());
	}
	// dynamic test
	if (tgt&rqtDyn){ 
		collide::ray_defs Q		(start,dir,R.range,CDB::OPT_ONLYNEAREST|CDB::OPT_CULL,tgt);
		// traverse object database
		u32			d_flags =	STYPE_COLLIDEABLE|((tgt&rqtObstacle)?STYPE_OBSTACLE:0)|((tgt&rqtShape)?STYPE_SHAPE:0);
		g_SpatialSpace->q_ray	(r_spatial,0,d_flags,start,dir,range);
		// Determine visibility for dynamic part of scene
		for (u32 o_it=0; o_it<r_spatial.size(); o_it++){
			ISpatial*	spatial			= r_spatial[o_it];
			CObject*	collidable		= spatial->dcast_CObject();
			if			(0==collidable)				continue;
			if			(collidable==ignore_object)	continue;
			ECollisionFormType tp		= collidable->collidable.model->Type();
			if (((tgt&(rqtObject|rqtObstacle))&&(tp==cftObject))||((tgt&rqtShape)&&(tp==cftShape))){
				u32		C	= D3DCOLOR_XRGB	(64,64,64);
				Q.range		= R.range;
				if (collidable->collidable.model->_RayQuery(Q,r_temp)){
					C				= D3DCOLOR_XRGB(128,128,196);
					R.set_if_less	(r_temp.r_begin());
				}
#ifdef DEBUG
				if (bDebug){
					Fsphere	S;		S.P = spatial->spatial.sphere.P; S.R = spatial->spatial.sphere.R;
					m_pRender->dbgAddSphere(S,C);
					//dbg_S.push_back	(mk_pair(S,C));
				}
#endif
			}
		}
	}
	return (R.element>=0);
}
Esempio n. 4
0
void	CActor::PickupModeUpdate_COD	()
{
	if (Level().CurrentViewEntity() != this || !g_b_COD_PickUpMode) return;
		
	if (!g_Alive() || eacFirstEye != cam_active) 
	{
		CurrentGameUI()->UIMainIngameWnd->SetPickUpItem(NULL);
		return;
	};
	
	CFrustum						frustum;
	frustum.CreateFromMatrix		(Device.mFullTransform, FRUSTUM_P_LRTB|FRUSTUM_P_FAR);

	ISpatialResult.clear_not_free	();
	g_SpatialSpace->q_frustum		(ISpatialResult, 0, STYPE_COLLIDEABLE, frustum);

	float maxlen					= 1000.0f;
	CInventoryItem* pNearestItem	= NULL;

	for (u32 o_it=0; o_it<ISpatialResult.size(); o_it++)
	{
		ISpatial*		spatial	= ISpatialResult[o_it];
		CInventoryItem*	pIItem	= smart_cast<CInventoryItem*> (spatial->dcast_CObject        ());

		if (0 == pIItem)											continue;
		if (pIItem->object().H_Parent() != NULL)					continue;
		if (!pIItem->CanTake())										continue;
		if ( smart_cast<CExplosiveRocket*>( &pIItem->object() ) )	continue;

		CGrenade*	pGrenade	= smart_cast<CGrenade*> (spatial->dcast_CObject        ());
		if (pGrenade && !pGrenade->Useful())						continue;

		CMissile*	pMissile	= smart_cast<CMissile*> (spatial->dcast_CObject        ());
		if (pMissile && !pMissile->Useful())						continue;
		
		Fvector A, B, tmp; 
		pIItem->object().Center			(A);
		if (A.distance_to_sqr(Position())>4)						continue;

		tmp.sub(A, cam_Active()->vPosition);
		B.mad(cam_Active()->vPosition, cam_Active()->vDirection, tmp.dotproduct(cam_Active()->vDirection));
		float len = B.distance_to_sqr(A);
		if (len > 1)												continue;

		if (maxlen>len && !pIItem->object().getDestroy())
		{
			maxlen = len;
			pNearestItem = pIItem;
		};
	}

	if(pNearestItem)
	{
		CFrustum					frustum;
		frustum.CreateFromMatrix	(Device.mFullTransform,FRUSTUM_P_LRTB|FRUSTUM_P_FAR);
		if (!CanPickItem(frustum, Device.vCameraPosition, &pNearestItem->object()))
			pNearestItem = NULL;
	}
	if (pNearestItem && pNearestItem->cast_game_object())
	{
		if (Level().m_feel_deny.is_object_denied(pNearestItem->cast_game_object()))
				pNearestItem = NULL;
	}
	if (pNearestItem && pNearestItem->cast_game_object())
	{
		if(!pNearestItem->cast_game_object()->getVisible())
				pNearestItem = NULL;
	}

	CurrentGameUI()->UIMainIngameWnd->SetPickUpItem(pNearestItem);

	if (pNearestItem && m_bPickupMode)
	{
		CUsableScriptObject*	pUsableObject = smart_cast<CUsableScriptObject*>(pNearestItem);
		if(pUsableObject && (!m_pUsableObject))
			pUsableObject->use(this);

		//подбирание объекта
		Game().SendPickUpEvent(ID(), pNearestItem->object().ID());
	}
};
Esempio n. 5
0
BOOL CObjectSpace::_RayTest	( const Fvector &start, const Fvector &dir, float range, collide::rq_target tgt, collide::ray_cache* cache, CObject* ignore_object)
{
	VERIFY					(_abs(dir.magnitude()-1)<EPS);
	r_temp.r_clear			();

	xrc.ray_options			(CDB::OPT_ONLYFIRST);
	collide::ray_defs	Q	(start,dir,range,CDB::OPT_ONLYFIRST,tgt);

	// dynamic test
	if (tgt&rqtDyn){
		u32			d_flags =	STYPE_COLLIDEABLE|((tgt&rqtObstacle)?STYPE_OBSTACLE:0)|((tgt&rqtShape)?STYPE_SHAPE:0);
		// traverse object database
		g_SpatialSpace->q_ray	(r_spatial,0,d_flags,start,dir,range);
		// Determine visibility for dynamic part of scene
		for (u32 o_it=0; o_it<r_spatial.size(); o_it++)
		{
			ISpatial*	spatial			= r_spatial[o_it];
			CObject*	collidable		= spatial->dcast_CObject	();
			if (collidable && (collidable!=ignore_object))	{
				ECollisionFormType tp	= collidable->collidable.model->Type();
				if ((tgt&(rqtObject|rqtObstacle))&&(tp==cftObject)&&collidable->collidable.model->_RayQuery(Q,r_temp))	return TRUE;
				if ((tgt&rqtShape)&&(tp==cftShape)&&collidable->collidable.model->_RayQuery(Q,r_temp))		return TRUE;
			}
		}
	}
	// static test
	if (tgt&rqtStatic){
		// If we get here - test static model
		if (cache) 
		{
			// 0. similar query???
			if (cache->similar(start,dir,range))	{
				return cache->result;
			}

			// 1. Check cached polygon
			float _u,_v,_range;
			if (CDB::TestRayTri(start,dir,cache->verts,_u,_v,_range,false)) 
			{
				if (_range>0 && _range<range) return TRUE;
			}
			
			// 2. Polygon doesn't pick - real database query
			xrc.ray_query	(&Static,start,dir,range);
			if (0==xrc.r_count()) {
				cache->set		(start,dir,range,FALSE);
				return FALSE;
			} else {
				// cache polygon
				cache->set		(start,dir,range,TRUE);
				CDB::RESULT*	R	= xrc.r_begin();
				CDB::TRI&		T	= Static.get_tris() [ R->id ];
				Fvector*		V	= Static.get_verts();
				cache->verts[0].set	(V[T.verts[0]]);
				cache->verts[1].set	(V[T.verts[1]]);
				cache->verts[2].set	(V[T.verts[2]]);
				return TRUE;
			}
		} else {
			xrc.ray_query		(&Static,start,dir,range);
			return xrc.r_count	();
		}
	}
	return FALSE;
}
Esempio n. 6
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 );
	}
}