Пример #1
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;
	}
}
Пример #2
0
void CActor::cam_Update(float dt, float fFOV)
{
	if(m_holder)		return;

	if( (mstate_real & mcClimb) && (cam_active!=eacFreeLook) )
		camUpdateLadder(dt);
	on_weapon_shot_update();
	float y_shift =0;
	
	if( GamePersistent().GameType() != eGameIDSingle && ik_cam_shift && character_physics_support() && character_physics_support()->ik_controller() )
	{
		y_shift = character_physics_support()->ik_controller()->Shift();
		float cam_smooth_k = 1.f;
		if(_abs(y_shift-current_ik_cam_shift)>ik_cam_shift_tolerance)
		{

			cam_smooth_k = 1.f - ik_cam_shift_speed * dt/0.01f;

		}

		if(_abs(y_shift)<ik_cam_shift_tolerance/2.f)
			cam_smooth_k = 1.f - ik_cam_shift_speed * 1.f/0.01f * dt;
		clamp( cam_smooth_k, 0.f, 1.f );
		current_ik_cam_shift = cam_smooth_k * current_ik_cam_shift + y_shift * ( 1.f - cam_smooth_k );
	} else
		current_ik_cam_shift = 0;

	Fvector point		= {0,CameraHeight() + current_ik_cam_shift,0}; 
	Fvector dangle		= {0,0,0};
	Fmatrix				xform;
	xform.setXYZ		(0,r_torso.yaw,0);
	xform.translate_over(XFORM().c);

	// lookout
	if (this == Level().CurrentControlEntity())
		cam_Lookout( xform, point.y  );


	if (!fis_zero(r_torso.roll))
	{
		float radius		= point.y*0.5f;
		float valid_angle	= r_torso.roll/2.f;
		calc_point			(point,radius,0,valid_angle);
		dangle.z			= (PI_DIV_2-((PI+valid_angle)/2));
	}

	float flCurrentPlayerY	= xform.c.y;

	// Smooth out stair step ups
	if ((character_physics_support()->movement()->Environment()==CPHMovementControl::peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){
		fPrevCamPos			+= dt*1.5f;
		if (fPrevCamPos > flCurrentPlayerY)
			fPrevCamPos		= flCurrentPlayerY;
		if (flCurrentPlayerY-fPrevCamPos>0.2f)
			fPrevCamPos		= flCurrentPlayerY-0.2f;
		point.y				+= fPrevCamPos-flCurrentPlayerY;
	}else{
		fPrevCamPos			= flCurrentPlayerY;
	}

	float _viewport_near			= VIEWPORT_NEAR;
	// calc point
	xform.transform_tiny			(point);

	CCameraBase* C					= cam_Active();

	C->Update						(point,dangle);
	C->f_fov						= fFOV;

	if(eacFirstEye != cam_active)
	{
		cameras[eacFirstEye]->Update	(point,dangle);
		cameras[eacFirstEye]->f_fov		= fFOV;
	} 
	if (Level().CurrentEntity() == this)
	{
		collide_camera( *cameras[eacFirstEye], _viewport_near, this );
	}
	if( psActorFlags.test(AF_PSP) )
	{
		Cameras().UpdateFromCamera			(C);
	}else
	{
		Cameras().UpdateFromCamera			(cameras[eacFirstEye]);
	}

	fCurAVelocity			= vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta;
	vPrevCamDir				= cameras[eacFirstEye]->vDirection;

#ifdef DEBUG
	if( dbg_draw_camera_collision )
	{
		dbg_draw_viewport( *cameras[eacFirstEye], _viewport_near );
		dbg_draw_viewport( Cameras(), _viewport_near );
	}
#endif

	if (Level().CurrentEntity() == this)
	{
		Level().Cameras().UpdateFromCamera	(C);
		if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){
			Cameras().ApplyDevice	(_viewport_near);
		}
	}
}
Пример #3
0
void CActor::cam_Update(float dt, float fFOV)
{
	if(m_holder)		return;

	if(mstate_real & mcClimb&&cam_active!=eacFreeLook)
		camUpdateLadder(dt);

	Fvector point={0,CameraHeight(),0}, dangle={0,0,0};
	

	Fmatrix				xform,xformR;
	xform.setXYZ		(0,r_torso.yaw,0);
	xform.translate_over(XFORM().c);

	// lookout
	if (this == Level().CurrentControlEntity())
	{
		if (!fis_zero(r_torso_tgt_roll)){
			Fvector src_pt,tgt_pt;
			float radius		= point.y*0.5f;
			float alpha			= r_torso_tgt_roll/2.f;
			float dZ			= ((PI_DIV_2-((PI+alpha)/2)));
			calc_point			(tgt_pt,radius,0,alpha);
			src_pt.set			(0,tgt_pt.y,0);
			// init valid angle
			float valid_angle	= alpha;
			// xform with roll
			xformR.setXYZ		(-r_torso.pitch,r_torso.yaw,-dZ);
			Fmatrix33			mat; 
			mat.i				= xformR.i;
			mat.j				= xformR.j;
			mat.k				= xformR.k;
			// get viewport params
			float w,h;
			float c				= viewport_near(w,h); w/=2.f;h/=2.f;
			// find tris
			Fbox box;
			box.invalidate		();
			box.modify			(src_pt);
			box.modify			(tgt_pt);
			box.grow			(c);

			// query
			Fvector				bc,bd		;
			Fbox				xf			; 
			xf.xform			(box,xform)	;
			xf.get_CD			(bc,bd)		;

			xrXRC				xrc			;
			xrc.box_options		(0)			;
			xrc.box_query		(Level().ObjectSpace.GetStaticModel(), bc, bd)		;
			u32 tri_count		= xrc.r_count();
			if (tri_count)		{
				float da		= 0.f;
				BOOL bIntersect	= FALSE;
				Fvector	ext		= {w,h,VIEWPORT_NEAR/2};
				if (test_point(xrc,xform,mat,ext,radius,alpha)){
					da			= PI/1000.f;
					if (!fis_zero(r_torso.roll))
						da		*= r_torso.roll/_abs(r_torso.roll);
					float angle = 0.f;
					for (; _abs(angle)<_abs(alpha); angle+=da)
						if (test_point(xrc,xform,mat,ext,radius,angle)) { bIntersect=TRUE; break; } 
					valid_angle	= bIntersect?angle:alpha;
				} 
			}
			r_torso.roll		= valid_angle*2.f;
			r_torso_tgt_roll	= r_torso.roll;
		}
		else
		{	
			r_torso_tgt_roll = 0.f;
			r_torso.roll = 0.f;
		}
	}
	if (!fis_zero(r_torso.roll))
	{
		float radius		= point.y*0.5f;
		float valid_angle	= r_torso.roll/2.f;
		calc_point			(point,radius,0,valid_angle);
		dangle.z			= (PI_DIV_2-((PI+valid_angle)/2));
	}

	float flCurrentPlayerY	= xform.c.y;

	// Smooth out stair step ups
	if ((character_physics_support()->movement()->Environment()==peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){
		fPrevCamPos			+= dt*1.5f;
		if (fPrevCamPos > flCurrentPlayerY)
			fPrevCamPos		= flCurrentPlayerY;
		if (flCurrentPlayerY-fPrevCamPos>0.2f)
			fPrevCamPos		= flCurrentPlayerY-0.2f;
		point.y				+= fPrevCamPos-flCurrentPlayerY;
	}else{
		fPrevCamPos			= flCurrentPlayerY;
	}
	float _viewport_near			= VIEWPORT_NEAR;
	// calc point
	xform.transform_tiny			(point);

	CCameraBase* C					= cam_Active();

	if(eacFirstEye == cam_active)
	{
//		CCameraBase* C				= cameras[eacFirstEye];
	
		xrXRC						xrc			;
		xrc.box_options				(0)			;
		xrc.box_query				(Level().ObjectSpace.GetStaticModel(), point, Fvector().set(VIEWPORT_NEAR,VIEWPORT_NEAR,VIEWPORT_NEAR) );
		u32 tri_count				= xrc.r_count();
		if (tri_count)
		{
			_viewport_near			= 0.01f;
		}
		else
		{
			xr_vector<ISpatial*> ISpatialResult;
			g_SpatialSpacePhysic->q_box(ISpatialResult, 0, STYPE_PHYSIC, point, Fvector().set(VIEWPORT_NEAR,VIEWPORT_NEAR,VIEWPORT_NEAR));
			for (u32 o_it=0; o_it<ISpatialResult.size(); o_it++)
			{
				CPHShell*		pCPHS= smart_cast<CPHShell*>(ISpatialResult[o_it]);
				if (pCPHS)
				{
					_viewport_near			= 0.01f;
					break;
				}
			}
		}
	}
/*
	{
		CCameraBase* C				= cameras[eacFirstEye];
		float oobox_size			= 2*VIEWPORT_NEAR;


		Fmatrix						_rot;
		_rot.k						= C->vDirection;
		_rot.c						= C->vPosition;
		_rot.i.crossproduct			(C->vNormal,	_rot.k);
		_rot.j.crossproduct			(_rot.k,		_rot.i);

		
		Fvector						vbox; 
		vbox.set					(oobox_size, oobox_size, oobox_size);


		Level().debug_renderer().draw_aabb  (C->vPosition, 0.05f, 0.051f, 0.05f, D3DCOLOR_XRGB(0,255,0));
		Level().debug_renderer().draw_obb  (_rot, Fvector().div(vbox,2.0f), D3DCOLOR_XRGB(255,0,0));

		dMatrix3					d_rot;
		PHDynamicData::FMXtoDMX		(_rot, d_rot);

		CPHActivationShape			activation_shape;
		activation_shape.Create		(point, vbox, this);

		dBodySetRotation			(activation_shape.ODEBody(), d_rot);

		CPHCollideValidator::SetDynamicNotCollide(activation_shape);
		activation_shape.Activate	(vbox,1,1.f,0.0F);

		point.set					(activation_shape.Position());
		
		activation_shape.Destroy	();
	}
*/
	C->Update						(point,dangle);
	C->f_fov						= fFOV;
	if(eacFirstEye != cam_active)
	{
		cameras[eacFirstEye]->Update	(point,dangle);
		cameras[eacFirstEye]->f_fov		= fFOV;
	}
	
	if( psActorFlags.test(AF_PSP) )
	{
		Cameras().Update			(C);
	}else
	{
		Cameras().Update			(cameras[eacFirstEye]);
	}

	fCurAVelocity			= vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta;
	vPrevCamDir				= cameras[eacFirstEye]->vDirection;

	if (Level().CurrentEntity() == this)
	{
		Level().Cameras().Update	(C);
		if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){
			Cameras().ApplyDevice	(_viewport_near);
		}
	}
}
Пример #4
0
void CActor::cam_Update(float dt, float fFOV)
{
	if(m_holder)		return;

	if( (mstate_real & mcClimb) && (cam_active!=eacFreeLook) )
		camUpdateLadder(dt);
	on_weapon_shot_update();

	// Alex ADD: smooth crouch fix
	if (!CurrentHeight)CurrentHeight = CameraHeight();
	float HeightInterpolationSpeed = 9.f;
	if (CurrentHeight != CameraHeight() && !Device.dwPrecacheFrame)
	{
		CurrentHeight = (CurrentHeight * (1.0f - HeightInterpolationSpeed*dt)) + (CameraHeight() * HeightInterpolationSpeed*dt);
	}
	Fvector point = { 0, CurrentHeight, 0 };
	//Fvector point		= {0,CameraHeight(),0}; 
	
	Fvector dangle		= {0,0,0};
	Fmatrix				xform;
	xform.setXYZ		(0,r_torso.yaw,0);
	xform.translate_over(XFORM().c);

	// lookout
	if (this == Level().CurrentControlEntity())
		cam_Lookout( xform, point.y  );


	if (!fis_zero(r_torso.roll))
	{
		float radius		= point.y*0.5f;
		float valid_angle	= r_torso.roll/2.f;
		calc_point			(point,radius,0,valid_angle);
		dangle.z			= (PI_DIV_2-((PI+valid_angle)/2));
	}

	float flCurrentPlayerY	= xform.c.y;

	// Smooth out stair step ups
	if ((character_physics_support()->movement()->Environment()==peOnGround) && (flCurrentPlayerY-fPrevCamPos>0)){
		fPrevCamPos			+= dt*1.5f;
		if (fPrevCamPos > flCurrentPlayerY)
			fPrevCamPos		= flCurrentPlayerY;
		if (flCurrentPlayerY-fPrevCamPos>0.2f)
			fPrevCamPos		= flCurrentPlayerY-0.2f;
		point.y				+= fPrevCamPos-flCurrentPlayerY;
	}else{
		fPrevCamPos			= flCurrentPlayerY;
	}

	float _viewport_near			= VIEWPORT_NEAR;
	// calc point
	xform.transform_tiny			(point);

	CCameraBase* C					= cam_Active();

	C->Update						(point,dangle);
	C->f_fov						= fFOV;

	if(eacFirstEye != cam_active)
	{
		cameras[eacFirstEye]->Update	(point,dangle);
		cameras[eacFirstEye]->f_fov		= fFOV;
	} 
	if (Level().CurrentEntity() == this)
		collide_camera( *cameras[eacFirstEye], _viewport_near );

	if( psActorFlags.test(AF_PSP) )
	{
		Cameras().UpdateFromCamera			(C);
	}else
	{
		Cameras().UpdateFromCamera			(cameras[eacFirstEye]);
	}

	fCurAVelocity			= vPrevCamDir.sub(cameras[eacFirstEye]->vDirection).magnitude()/Device.fTimeDelta;
	vPrevCamDir				= cameras[eacFirstEye]->vDirection;

#ifdef DEBUG
	if( dbg_draw_camera_collision )
	{
		dbg_draw_viewport( *cameras[eacFirstEye], _viewport_near );
		dbg_draw_viewport( Cameras(), _viewport_near );
	}
#endif

	if (Level().CurrentEntity() == this)
	{
		Level().Cameras().UpdateFromCamera	(C);
		if(eacFirstEye == cam_active && !Level().Cameras().GetCamEffector(cefDemo)){
			Cameras().ApplyDevice	(_viewport_near);
		}
	}
}