예제 #1
0
void CNetworkPlayer::UpdateAim( bool bAiming )
{
	DEBUG_TRACE("CNetworkPlayer::UpdateAim");

	// Is the playerped not valid?
	if( !m_pPlayerPed )
		return;

	// Should we start aiming?
	if( bAiming && !IsAiming() )
	{
		// Terminate the old aim object if it's valid
		if ( m_pAimObject )
			m_pAimObject->Terminate ();

		// Delete the old aim object
		SAFE_DELETE( m_pAimObject );

		// Create the initial aim sync object if needed
		m_pAimObject = new CM2SyncObject( m_pPlayerPed->AimAt( GetLookAt() ) );

		// Mark as aiming
		SetAiming( true );
	}
	// Should we stop aiming?
	else if( !bAiming && IsAiming() )
	{
		// Terminate the old aim object if it's valid
		if ( m_pAimObject )
			m_pAimObject->Terminate ();

		// Delete the old aim sync object
		SAFE_DELETE( m_pAimObject );

		// Mark as not aiming
		SetAiming( false );
	}
	// Should we update the aim position
	else if( bAiming && IsAiming() )
	{
		// Is the aim sync object valid?
		if( m_pAimObject && !m_pAimObject->IsDone() )
		{
			// Update the aim position
			m_pAimObject->SetTarget( GetLookAt(), eTargetType::E_TYPE_AIM );
		}
		else if( m_pAimObject && m_pAimObject->IsDone() )
		{
			// Mark as not aiming to rebuild the object next pulse
			SetAiming( false );
		}
	}
}
예제 #2
0
void CNetworkPlayer::UpdateShot( bool bShooting )
{
	DEBUG_TRACE("CNetworkPlayer::UpdateShot");

	// Is the playerped not valid?
	if( !m_pPlayerPed )
		return;

	// Should we start shooting?
	if( bShooting && !IsShooting() )
	{
		// Terminate the old shot object if it's valid
		if ( m_pShootObject )
			m_pShootObject->Terminate ();

		// Delete the old shoot object
		SAFE_DELETE( m_pShootObject );

		// Terminate the old aim object if it's valid
		if ( m_pAimObject )
			m_pAimObject->Terminate ();

		// Delete the old aim object
		SAFE_DELETE( m_pAimObject );

		// Create the initial shoot sync object if needed
		m_pShootObject = new CM2SyncObject( m_pPlayerPed->ShootAt( GetLookAt() ) );

		// Mark as shooting
		SetShooting( true );
	}
	// Should we stop shooting?
	else if( !bShooting && IsShooting() )
	{
		// Terminate the old shot object if it's valid
		if ( m_pShootObject )
			m_pShootObject->Terminate ();

		// Delete the old aim sync object
		SAFE_DELETE( m_pShootObject );

		// Mark as not shooting
		SetShooting( false );

		// Are we aiming?
		if( IsAiming() )
		{
			// Mark as not aiming
			SetAiming( false );

			// Update the aim now!
			UpdateAim( true );
		}
	}
	// Should we update the aim position
	else if( bShooting && IsShooting() )
	{
		// Is the aim sync object valid?
		if( m_pShootObject && !m_pShootObject->IsDone() )
		{
			// Update the aim position
			m_pShootObject->SetTarget( GetLookAt(), eTargetType::E_TYPE_SHOOT );
		}
		else if( m_pShootObject && m_pShootObject->IsDone() )
		{
			// Mark as not shooting
			SetShooting( false );
		}
	}
}
예제 #3
0
//------------------------------------------------------------------------
void CGunTurret::ServerUpdate(SEntityUpdateContext &ctx, int update)
{
	//update parameters. SNH: cache these in MP since they never change.
	if(!gEnv->bMultiplayer)
	{
		UpdateEntityProperties();
	}

	IEntity *pCurrentTarget = gEnv->pEntitySystem->GetEntity(m_targetId);
	IActor  *pCurrentActor = GetActor(m_targetId);

	bool mg=false;
	bool rocket=false;

	if(IsOperational())
	{
		bool renew_target = false;

		//do this before, cause it's more important
		if(m_turretparams.TAC_check_time != 0.f)
		{
			if(m_checkTACTimer>m_turretparams.TAC_check_time)
			{
				m_checkTACTimer = 0.0f;
				IEntity *pClosest = GetClosestTACShell();

				if(pClosest)
				{
					ChangeTargetTo(pClosest);
					pCurrentTarget = pClosest;
				}
			}
			else
				m_checkTACTimer += ctx.fFrameTime;
		}

		//actually if(...), break at end
		while(pCurrentTarget)
		{
			if(InternalIsFiring(false))
				m_burstTimer += ctx.fFrameTime;
			else
				m_burstTimer = 0.f;

			ETargetClass t_class = GetTargetClass(pCurrentTarget);
			bool validClass = (t_class!=eTC_NotATarget);

			Vec3 tpos = PredictTargetPos(pCurrentTarget,false);
			bool inrange = IsInRange(tpos, t_class);

			if(m_rayTimer <= 0.f)
			{
				m_canShoot = IsTargetShootable(pCurrentTarget);
				m_rayTimer = (m_canShoot) ? 0.5f : 0.2f;
			}
			else
				m_rayTimer -= ctx.fFrameTime;

			if(!(validClass && inrange && m_canShoot))
			{
				m_abandonTargetTimer += ctx.fFrameTime;
			}
			else
				m_abandonTargetTimer = 0.0f;

			if(m_abandonTargetTimer > m_turretparams.abandon_target_time + m_randoms[eRV_AbandonTarget].val)
			{
				renew_target = true;
				m_randoms[eRV_AbandonTarget].New();
				break;
			}

			bool aim = inrange&&m_canShoot&&IsAiming(tpos, m_turretparams.aim_tolerance);
			mg = aim && !m_turretparams.search_only && IsTargetMGable(tpos);

			bool burst = (m_turretparams.burst_time == 0.f || UpdateBurst(ctx.fFrameTime));
			mg &= burst;

			// a bit less tolerant for rockets
			aim=aim&&IsAiming(tpos, m_turretparams.aim_tolerance*0.5f);

			rocket = aim && !m_turretparams.search_only && m_fm2 && t_class == eTC_Vehicle && IsTargetRocketable(tpos);

			if(g_pGameCVars->i_debug_turrets)
			{
				IRenderer *pRenderer = gEnv->pRenderer;
				static float white[4] = {1,1,1,1};
				float x = 5.f, y = 50.f, step1 = 15.f, /*step2 = 20.f, */size=1.3f;

				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Target: %s", pCurrentTarget->GetName());
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "InRange: %i", inrange);
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "CanShoot: %i", m_canShoot);
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "IsAiming: %i", aim);
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Burst: %i", burst);
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "MG: %i", mg);
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "BurstTimer: %.2f", m_burstTimer);
				//pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Rocket: %i", rocket);
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "TargetPos: %.1f %.1f %.1f", tpos.x, tpos.y, tpos.z);
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Abandon: %.2f", m_abandonTargetTimer);
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "Update: %.2f", m_updateTargetTimer);
				pRenderer->Draw2dLabel(x, y+=step1, size, white, false, "GoalYaw: %.2f, GoalPitch: %.2f", m_goalYaw, m_goalPitch);
			}

			break;
		}

		m_updateTargetTimer += ctx.fFrameTime;

		if(renew_target || m_updateTargetTimer > m_turretparams.update_target_time+m_randoms[eRV_UpdateTarget].Val())
		{
			IEntity *pClosestTAC = GetClosestTACShell();
			IEntity *pClosest = (pClosestTAC) ? pClosestTAC : GetClosestTarget();

			// change target if tac shell, or other target closer than current
			// otherwise, only change after abandoning time is exceeded
			if(pClosestTAC || (pClosest && pClosest->GetId()!=m_targetId) || (!pClosest && !(m_abandonTargetTimer>0.f && m_abandonTargetTimer<=m_turretparams.abandon_target_time)))
			{
				ChangeTargetTo(pClosest);
				pCurrentTarget = pClosest;
			}

			m_updateTargetTimer = 0.f;
			m_randoms[eRV_UpdateTarget].New();
		}

		if(pCurrentTarget)
		{
			if(m_turretparams.surveillance || IsTargetShootable(pCurrentTarget))
				UpdateGoal(pCurrentTarget, ctx.fFrameTime);
		}
		else
		{
			if(m_turretparams.searching)
			{
				UpdateSearchingGoal(ctx.fFrameTime);
			}
		}
	}

	if(m_fm && mg != InternalIsFiring(false))
	{
		if(mg)
			InternalStartFire(false);
		else
			InternalStopFire(false);
	}

	if(m_fm2 && rocket != InternalIsFiring(true))
	{
		if(rocket)
			InternalStartFire(true);
		else
			InternalStopFire(true);
	}
}