//------------------------------------------------------------------------
void CVehicleSeatActionMovement::OnAction(const TVehicleActionId actionId, int activationMode, float value)
{
	if (actionId == eVAI_MoveForward)
		m_actionForward = value;
	else if (actionId == eVAI_MoveBack)
		m_actionForward = -value;

	IVehicleMovement* pMovement = m_pVehicle->GetMovement();
	CRY_ASSERT(pMovement);

	pMovement->OnAction(actionId, activationMode, value);
}
//------------------------------------------------------------------------
void CVehicleSeatActionMovement::StopUsing()
{
	IActorSystem* pActorSystem = CCryAction::GetCryAction()->GetIActorSystem();
	CRY_ASSERT(pActorSystem);

	IVehicleMovement* pMovement = m_pVehicle->GetMovement();
	if (!pMovement)
		return;

	CRY_ASSERT(m_pSeat);

	// default to continuing for a bit
	m_delayedStop = 0.8f;

	IActor* pActor = pActorSystem->GetActor(m_pSeat->GetPassenger());

	if (pActor && pActor->IsPlayer())
	{
		// if stopped already don't go anywhere
		IPhysicalEntity*   pPhys = m_pVehicle->GetEntity()->GetPhysics();
		pe_status_dynamics status;
		if (pPhys && pPhys->GetStatus(&status))
		{
			if (status.v.GetLengthSquared() < 25.0f)
				m_delayedStop = 0.0f;
		}

		if (m_actionForward > 0.0f)
			m_delayedStop = 1.5f;

		if (pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
			m_delayedStop *= 2.0f;

		m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate);

		// prevent full pedal being kept pressed, but give it a bit
		pMovement->OnAction(eVAI_MoveForward, eAAM_OnPress, 0.1f);
	}
	else
	{
		if (pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
		{
			m_delayedStop = 0.0f;
			m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate);
		}
		else
		{
			pMovement->StopDriving();
		}
	}
}
//------------------------------------------------------------------------
void CVehicleSeatActionMovement::Update(const float deltaTime)
{
	IVehicleMovement* pMovement = m_pVehicle->GetMovement();
	CRY_ASSERT(pMovement);

	bool isReadyToStopEngine = true;

	if (isReadyToStopEngine)
	{
		if (m_delayedStop > 0.0f)
			m_delayedStop -= deltaTime;

		if (m_delayedStop <= 0.0f)
		{
			m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_NoUpdate);
			pMovement->StopDriving();
		}
	}
}
//------------------------------------------------------------------------
void CVehicleSeatActionMovement::StartUsing(EntityId passengerId)
{
	IActorSystem* pActorSystem = CCryAction::GetCryAction()->GetIActorSystem();
	CRY_ASSERT(pActorSystem);

	IActor* pActor = pActorSystem->GetActor(passengerId);
	CRY_ASSERT(pActor);

	IVehicleMovement* pMovement = m_pVehicle->GetMovement();
	CRY_ASSERT(pMovement);

	if (!pMovement)
		return;

	if (m_delayedStop >= 0.0f)
	{
		m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_NoUpdate);
		m_delayedStop = 0.0f;

		pMovement->StopDriving();
	}

	pMovement->StartDriving(passengerId);
}
Esempio n. 5
0
//------------------------------------------------------------------------
void CVehicleClient::OnAction(IVehicle* pVehicle, EntityId actorId, const ActionId& actionId, int activationMode, float value)
{
	assert(pVehicle);
 	if (!pVehicle)
		return;
	
  TActionNameIdMap::const_iterator ite = m_actionNameIds.find(actionId);
	if (ite == m_actionNameIds.end())
    return;

	IVehicleMovement *pMovement = pVehicle->GetMovement();
	const bool isAir = pMovement && pMovement->GetMovementType()==IVehicleMovement::eVMT_Air;

	IVehicleSeat* pCurrentSeat = pVehicle->GetSeatForPassenger(actorId);
	const bool isThirdPerson = pCurrentSeat && pCurrentSeat->GetView(pCurrentSeat->GetCurrentView())->IsThirdPerson();
	const bool isDriver = pCurrentSeat && pCurrentSeat->IsDriver();

	switch (ite->second)
  {
  case (eVAI_XIMoveX):	
    {
			if(pMovement && pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
			{
				//strafe instead of turning for air vehicles
				if(value>0.f)
				{
					pVehicle->OnAction(eVAI_StrafeRight, eAAM_OnPress, value, actorId);
					m_bMovementFlagRight = true;
				}
				else if(value==0.f)
				{
					if(m_bMovementFlagRight)
					{
						pVehicle->OnAction(eVAI_StrafeRight, eAAM_OnRelease, 0.f, actorId);
						m_bMovementFlagRight = false;
					}
					else if(m_bMovementFlagLeft)
					{
						pVehicle->OnAction(eVAI_StrafeLeft, eAAM_OnRelease, 0.f, actorId);
						m_bMovementFlagLeft = false;
					}
				}
				else//value<0
				{
					pVehicle->OnAction(eVAI_StrafeLeft, eAAM_OnPress, -value, actorId);
					m_bMovementFlagLeft = true;
				}
			}
			else
			{
				if(value>0.f)
				{
					pVehicle->OnAction(eVAI_TurnRight, eAAM_OnPress, value, actorId);
					m_bMovementFlagRight = true;
				}
				else if(value==0.f)
				{
					if(m_bMovementFlagRight)
					{
						pVehicle->OnAction(eVAI_TurnRight, eAAM_OnRelease, 0.f, actorId);
						m_bMovementFlagRight = false;
					}
					else if(m_bMovementFlagLeft)
					{
						pVehicle->OnAction(eVAI_TurnLeft, eAAM_OnRelease, 0.f, actorId);
						m_bMovementFlagLeft = false;
					}
				}
				else//value<0
				{
					pVehicle->OnAction(eVAI_TurnLeft, eAAM_OnPress, -value, actorId);
					m_bMovementFlagLeft = true;
				}
			}
			break;
		}
  case (eVAI_XIMoveY):
		{
			EVehicleActionIds eForward = eVAI_MoveForward;
			EVehicleActionIds eBack = eVAI_MoveBack;
			if(!strcmp("Asian_helicopter",pVehicle->GetEntity()->GetClass()->GetName()))
			{
				eForward = eVAI_MoveUp;
				eBack = eVAI_MoveDown;
			}

			if(value>0.f)
			{
				pVehicle->OnAction(eForward, eAAM_OnPress, value, actorId);
				m_bMovementFlagForward = true;
			}
			else if(value==0.f)
			{
				if(m_bMovementFlagForward)
				{
					pVehicle->OnAction(eForward, eAAM_OnRelease, 0.f, actorId);
					m_bMovementFlagForward = false;
				}
				else if(m_bMovementFlagBack)
				{
					pVehicle->OnAction(eBack, eAAM_OnRelease, 0.f, actorId);
					m_bMovementFlagBack = false;
				}
			}			
			else//value<0.f
			{
				pVehicle->OnAction(eBack, eAAM_OnPress, -value, actorId);
				m_bMovementFlagBack = true;
			}
      break;
		}
	case (eVAI_XIRotateYaw):
		{
			if (isAir && (isDriver || isThirdPerson))
			{
				pVehicle->OnAction(eVAI_RotateYaw, eAAM_OnPress, value / 5.f, actorId);
			}
			else
			{
				// action is sent to vehicle in PreUpdate, so it is repeated every frame.
				m_xiRotation.x = (value*value*value);
			}
			break;
		}
	case (eVAI_XIRotatePitch):
		{
			if (isAir && (isDriver || isThirdPerson))
			{
				pVehicle->OnAction(eVAI_RotatePitch, eAAM_OnPress, value / 5.f, actorId);
			}
			else
			{
				// action is sent to vehicle in PreUpdate, so it is repeated every frame
				m_xiRotation.y = -(value*value*value);
				if(g_pGameCVars->cl_invertController)
					m_xiRotation.y*=-1;
			}
			break;
		}
	case (eVAI_RotateYaw):
		{
			// attempt to normalise the input somewhat (to bring it in line with controller input).
			const float	scale = 0.75f, limit = 6.0f;
			value = clamp_tpl<float>(scale * value * gEnv->pTimer->GetFrameTime(), -limit, limit);

			if (isAir)
			{
				value *= 10.f;
			}

			pVehicle->OnAction(ite->second, activationMode, value, actorId);
			break;
		}
	case (eVAI_RotatePitch):
		{
			// attempt to normalise the input somewhat (to bring it in line with controller input).
			const float	scale = 0.75f, limit = 6.0f;
			value = clamp_tpl<float>(scale * value * gEnv->pTimer->GetFrameTime(), -limit, limit);

			if (g_pGameCVars->cl_invertMouse)
				value *= -1.f;

			if (isAir)
			{
				value *= 10.f;
			}

			pVehicle->OnAction(ite->second, activationMode, value, actorId);
			break;
		}
  case (eVAI_TurnLeft):
    {
      if (activationMode == eAAM_OnPress || activationMode == eAAM_OnRelease)
        m_fLeftRight -= value*2.f - 1.f;
			m_fLeftRight = CLAMP(m_fLeftRight, -1.0f, 1.0f);
      pVehicle->OnAction(ite->second, activationMode, -m_fLeftRight, actorId);
      break;
    }
  case (eVAI_TurnRight):
    {
      if (activationMode == eAAM_OnPress || activationMode == eAAM_OnRelease)
        m_fLeftRight += value*2.f - 1.f;
			m_fLeftRight = CLAMP(m_fLeftRight, -1.0f, 1.0f);
      pVehicle->OnAction(ite->second, activationMode, m_fLeftRight, actorId);
      break;
    }  
  case (eVAI_MoveForward):
    {
      if (activationMode == eAAM_OnPress || activationMode == eAAM_OnRelease)
        m_fForwardBackward += value*2.f - 1.f;

			if(activationMode == eAAM_OnRelease)
				m_fForwardBackward = CLAMP(m_fForwardBackward, 0.0f, 1.0f);
			else
				m_fForwardBackward = CLAMP(m_fForwardBackward, -1.0f, 1.0f);
      pVehicle->OnAction(ite->second, activationMode, m_fForwardBackward, actorId);
      break;
    }
  case (eVAI_MoveBack):
    {
      if (activationMode == eAAM_OnPress || activationMode == eAAM_OnRelease)
        m_fForwardBackward -= value*2.f - 1.f;

			if(activationMode == eAAM_OnRelease)
				m_fForwardBackward = CLAMP(m_fForwardBackward, -1.0f, 0.0f);
			else
				m_fForwardBackward = CLAMP(m_fForwardBackward, -1.0f, 1.0f);
      pVehicle->OnAction(ite->second, activationMode, -m_fForwardBackward, actorId);
      break;
    }  
	case (eVAI_ZoomIn):
	case (eVAI_ZoomOut):
			break;
  default:
		pVehicle->OnAction(ite->second, activationMode, value, actorId);
    break;		
	}
}
Esempio n. 6
0
//------------------------------------------------------------------------
void CVehicleViewSteer::Update(float dt)
{
	IEntity* pEntity = m_pVehicle->GetEntity();
	assert(pEntity);

	IVehicleMovement* pVehicleMovement = m_pVehicle->GetMovement();
	if (pVehicleMovement == NULL)
		return;

	IPhysicalEntity* pPhysEntity = pEntity->GetPhysics();
	if (!pPhysEntity)
		return;

	pe_status_dynamics dynStatus;
	pPhysEntity->GetStatus(&dynStatus);

	SMovementState movementState;
	pVehicleMovement->GetMovementState(movementState);
	const float     pedal        = pVehicleMovement->GetEnginePedal();
	const float     maxSpeed     = movementState.maxSpeed;
	const Matrix34 &pose         = m_pAimPart ? m_pAimPart->GetWorldTM() : pEntity->GetWorldTM();
	const Vec3      entityPos    = pose.GetColumn3();
	const Vec3      xAxis        = pose.GetColumn0();
	const Vec3      yAxis        = pose.GetColumn1();
	const Vec3      zAxis        = pose.GetColumn2();
	const float     forwardSpeed = dynStatus.v.dot(yAxis);
	const float     speedNorm    = clamp_tpl(forwardSpeed / maxSpeed, 0.0f, 1.0f);
	const Vec3      maxRotation  = m_maxRotation + speedNorm * (m_maxRotation2 - m_maxRotation);

	CalcLookAt(pose);
	if (m_lookAt.IsValid())
	{
		if (!m_lastOffset.IsValid())
		{
			m_position             = pose * m_localSpaceCameraOffset;
			m_lastOffset           = m_position - m_lookAt;
			m_lastOffsetBeforeElev = m_lastOffset;
		}

		Vec3 offset = m_lastOffsetBeforeElev;

		if (pedal < 0.1f && forwardSpeed < 1.0f)
		{
			// Going Backwards
			m_flags &= ~(eVCam_goingForwards | m_forwardFlags);
			m_flags |= m_backwardsFlags;
		}

		if (offset.dot(yAxis) < 0.8f && forwardSpeed > 1.f)
		{
			// Going Forwards
			m_flags &= ~m_backwardsFlags;
			m_flags |= eVCam_goingForwards | m_forwardFlags;
		}

		float sensitivity = (1.f - speedNorm) * m_stickSensitivity.z + speedNorm * m_stickSensitivity2.z;
		float rotate      = -m_rotatingAction.z * sensitivity;
		rotate = rotate * dt;

		if (zAxis.z > 0.1f)
		{
			// Safe to update curYaw
			Vec3 projectedX = xAxis;
			projectedX.z = 0.f;
			Vec3 projectedY = yAxis;
			projectedY.z = 0.f;
			const float newYaw    = atan2_tpl(offset.dot(projectedX), -(offset.dot(projectedY)));
			const float maxChange = DEG2RAD(270.f) * dt;
			const float delta     = clamp_tpl(newYaw - m_curYaw, -maxChange, +maxChange);
			m_curYaw += delta;
		}

		// Rotation Action
		{
			if (m_flags & eVCam_rotationClamp)
			{
				float newYaw = clamp_tpl(m_curYaw + rotate, -maxRotation.z, +maxRotation.z);
				rotate        = newYaw - m_curYaw;
				rotate        = clamp_tpl(newYaw - m_curYaw, -fabsf(rotate), +fabsf(rotate));
				m_rotation.z += rotate;
			}
			else
			{
				m_rotation.z = 0.f;
			}

			if (speedNorm > 0.1f)
			{
				float reduce = dt * 1.f;
				m_rotation.z = m_rotation.z - reduce * m_rotation.z / (fabsf(m_rotation.z) + reduce);
			}
		}

		// Ang Spring
		{
			float angSpeedCorrection = dt * dt * m_angSpeedCorrection / (dt * m_angSpeedCorrection + 1.f) * dynStatus.w.z;
			if ((m_flags & eVCam_rotationSpring) == 0)
			{
				m_angReturnSpeed   = 0.f;
				angSpeedCorrection = 0.f;
			}

			float difference = m_rotation.z - m_curYaw;
			float relax      = difference * (m_angReturnSpeed * dt) / ((m_angReturnSpeed * dt) + 1.f);

			const float delta = +relax + angSpeedCorrection + rotate;
			m_curYaw += delta;

			Matrix33 rot = Matrix33::CreateRotationZ(delta);
			offset = rot * offset;

			// Lerp the spring speed
			float angSpeedTarget = m_angReturnSpeed1 + speedNorm * (m_angReturnSpeed2 - m_angReturnSpeed1);
			m_angReturnSpeed     += (angSpeedTarget - m_angReturnSpeed) * (dt / (dt + 0.3f));
			m_angSpeedCorrection += (m_angSpeedCorrection0 - m_angSpeedCorrection) * (dt / (dt + 0.3f));
		}

		if (!offset.IsValid()) offset = m_lastOffset;

		// Velocity influence
		Vec3 displacement = -((2.f - speedNorm) * dt) * dynStatus.v;// - yAxis*(0.0f*speedNorm*(yAxis.dot(dynStatus.v))));

		float dot = offset.dot(displacement);
		if (dot < 0.f)
		{
			displacement = displacement + offset * -0.1f * (offset.dot(displacement) / offset.GetLengthSquared());
		}
		offset = offset + displacement;

		const float radius0   = fabsf(m_localSpaceCameraOffset.y);
		const float minRadius = radius0 * m_radiusMin;
		const float maxRadius = radius0 * m_radiusMax;
		float       radiusXY  = sqrtf(sqr(offset.x) + sqr(offset.y));

		Vec3 offsetXY = offset;
		offsetXY.z = 0.f;
		Vec3  accelerationV = (dynStatus.v - m_lastVehVel);
		float acceleration  = offsetXY.dot(accelerationV) / radiusXY;

		m_lastVehVel = dynStatus.v;
		m_radiusVel -= acceleration;
		m_radius    += m_radiusVel * dt - dt * m_radiusVelInfluence * offsetXY.dot(dynStatus.v) / radiusXY;
		m_radiusVel *= expf(-dt * m_radiusDampRate);
		m_radius    += (radius0 - m_radius) * (dt * m_radiusRelaxRate) / (dt * m_radiusRelaxRate + 1.f);
		m_radius     = clamp_tpl(m_radius, minRadius, maxRadius);
		offset       = offset * (m_radius / radiusXY);

		// Vertical motion
		float targetOffsetHeight = m_localSpaceCameraOffset.z * (m_radius / radius0);
		float oldOffsetHeight    = offset.z;
		offset.z += (targetOffsetHeight - offset.z) * (dt / (dt + 0.3f));
		Limit(offset.z, targetOffsetHeight - 2.f, targetOffsetHeight + 2.f);
		float verticalChange = offset.z - oldOffsetHeight;

		m_lastOffsetBeforeElev = offset;

		// Add up and down camera tilt
		{
			offset.z     -= verticalChange;
			m_rotation.x += dt * m_stickSensitivity.x * m_rotatingAction.x;
			m_rotation.x  = clamp_tpl(m_rotation.x, -maxRotation.x, +maxRotation.x);

			float elevAngleVehicle = m_inheritedElev * yAxis.z;     // yAxis.z == approx elevation angle

			float elevationAngle = m_rotation.x - elevAngleVehicle;

			float sinElev, cosElev;
			sincos_tpl(elevationAngle, &sinElev, &cosElev);
			float horizLen    = sqrtf(offset.GetLengthSquared2D());
			float horizLenNew = horizLen * cosElev - sinElev * offset.z;
			if (horizLen > 1e-4f)
			{
				horizLenNew /= horizLen;
				offset.x    *= horizLenNew;
				offset.y    *= horizLenNew;
				offset.z     = offset.z * cosElev + sinElev * horizLen;
			}
			offset.z += verticalChange;
		}

		if (!offset.IsValid()) offset = m_lastOffset;

		m_position = m_lookAt + offset;

		// Perform world intersection test.
		{
			// Initialise sphere and direction.
			primitives::sphere sphere;

			sphere.center = m_lookAt;
			sphere.r      = g_SteerCameraRadius;

			Vec3 direction = m_position - m_lookAt;

			// Calculate camera bounds.
			AABB localBounds;

			m_pVehicle->GetEntity()->GetLocalBounds(localBounds);

			const float cameraBoundsScale = 0.75f;

			localBounds.min *= cameraBoundsScale;
			localBounds.max *= cameraBoundsScale;

			OBB cameraBounds;

			Matrix34 worldTM = m_pVehicle->GetEntity()->GetWorldTM();

			cameraBounds.SetOBBfromAABB(Matrix33(worldTM), localBounds);

			// Try to find point on edge of camera bounds to begin swept sphere intersection test.
			Vec3 rayBoxIntersect;

			if (Intersect::Ray_OBB(Ray(m_position, -direction), worldTM.GetTranslation(), cameraBounds, rayBoxIntersect) > 0)
			{
				Vec3 temp = m_position - rayBoxIntersect;

				if (direction.Dot(temp) > 0.0f)
				{
					sphere.center = rayBoxIntersect;
					direction     = temp;
				}
			}

			// Perform swept sphere intersection test against world.
			geom_contact* pContact = NULL;

			IPhysicalEntity* pSkipEntities[10];

			float distance = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, direction, ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid,
			                                                                  &pContact, 0, (geom_colltype_player << rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0,
			                                                                  pSkipEntities, m_pVehicle->GetSkipEntities(pSkipEntities, 10));

			if (distance > 0.0f)
			{
				// Sweep intersects world so calculate new offset.
				offset = (sphere.center + (direction.GetNormalizedSafe() * distance)) - m_lookAt;
			}
		}

		Interpolate(m_lastOffset, offset, 10.f, dt);

		m_position = m_lookAt + m_lastOffset;
	}
	else
	{
		CRY_ASSERT_MESSAGE(0, "camera will fail because lookat position is invalid");
	}

	m_rotatingAction.zero();
}
Esempio n. 7
0
//------------------------------------------------------------------------
void CVehiclePartAnimated::SetDrivingProxy(bool bDrive)
{
	IVehicleMovement* pMovement = m_pVehicle->GetMovement();
	if (!(pMovement && pMovement->UseDrivingProxy()))
		return;

	if (0 == m_hullMatId[bDrive]) // 0 means, nothin to do
		return;

	if (!m_pCharInstance)
		return;

	ISkeletonPose* pSkeletonPose = m_pCharInstance->GetISkeletonPose();
	if (!pSkeletonPose)
		return;
	IDefaultSkeleton &rIDefaultSkeleton = m_pCharInstance->GetIDefaultSkeleton();
	IPhysicalEntity*  pPhysics          = m_pVehicle->GetEntity()->GetPhysics();
	if (!pPhysics)
		return;

	int id = rIDefaultSkeleton.GetJointIDByName("hull_proxy");

	if (id < 0)
	{
		m_hullMatId[0] = m_hullMatId[1] = 0;
		return;
	}

	int partid = pSkeletonPose->GetPhysIdOnJoint(id);

	if (partid == -1)
		return;

	pe_params_part params;
	params.partid = partid;
	params.ipart  = -1;
	if (!pPhysics->GetParams(&params) || !params.nMats)
		return;

	phys_geometry* pGeom = params.pPhysGeom;
	if (pGeom && pGeom->surface_idx < pGeom->nMats)
	{
		ISurfaceTypeManager* pSurfaceMan = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager();

		// initialize once
		if (m_hullMatId[0] < 0)
		{
			int         idDriving = 0;
			int         idOrig    = pGeom->pMatMapping[pGeom->surface_idx];
			const char* matOrig   = pSurfaceMan->GetSurfaceType(idOrig)->GetName();

			if (strstr(matOrig, "mat_metal"))
				idDriving = pSurfaceMan->GetSurfaceTypeByName("mat_metal_nofric")->GetId();
			else
			{
				string mat(matOrig);
				mat.append("_nofric");

				idDriving = pSurfaceMan->GetSurfaceTypeByName(mat.c_str(), NULL, false)->GetId();
			}

			//if (pDebug->GetIVal())
			//CryLog("%s looking up driving surface replacement for %s (id %i) -> got id %i", m_pVehicle->GetEntity()->GetName(), matOrig, idOrig, idDriving);

			if (idDriving > 0)
			{
				// store old and new id
				m_hullMatId[0] = idOrig;
				m_hullMatId[1] = idDriving;

				/*if (pDebug->GetIVal())
				   {
				   const char* matDriving = pSurfaceMan->GetSurfaceType(idDriving)->GetName();
				   CryLog("%s storing hull matId for swapping: %i (%s) -> %i (%s)", m_pVehicle->GetEntity()->GetName(), m_hullMatId[0], matOrig, m_hullMatId[1], matDriving);
				   }*/
			}
			else
				m_hullMatId[0] = m_hullMatId[1] = 0;
		}

		// only swap if materials available
		if (m_hullMatId[bDrive] > 0)
		{
#if ENABLE_VEHICLE_DEBUG
			if (VehicleCVars().v_debugdraw == eVDB_Parts)
				CryLog("%s swapping hull proxy from %i (%s) to matId %i (%s)", m_pVehicle->GetEntity()->GetName(), m_hullMatId[bDrive ^ 1], pSurfaceMan->GetSurfaceType(m_hullMatId[bDrive ^ 1])->GetName(), m_hullMatId[bDrive], pSurfaceMan->GetSurfaceType(m_hullMatId[bDrive])->GetName());
#endif

			for (int n = 0; n < pGeom->nMats; ++n)
			{
				pGeom->pMatMapping[n] = m_hullMatId[bDrive];
			}
		}
	}
}
Esempio n. 8
0
//------------------------------------------------------------------------
void CVehicleClient::OnAction(IVehicle* pVehicle, EntityId actorId, const ActionId& actionId, int activationMode, float value)
{
	assert(pVehicle);
 	if (!pVehicle)
		return;
	
  TActionNameIdMap::const_iterator ite = m_actionNameIds.find(actionId);
	if (ite == m_actionNameIds.end())
    return;

	switch (ite->second)
  {
  case (eVAI_XIMoveX):	
    {

			IVehicleMovement *pMovement = pVehicle->GetMovement();
			if (value < VEHICLE_GAMEPAD_DEADZONE && value > -VEHICLE_GAMEPAD_DEADZONE)
				value = 0.0f;

			if(pMovement && pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
			{
				//strafe instead of turning for air vehicles
				if(value>0.f)
				{
					pVehicle->OnAction(eVAI_StrafeRight, eAAM_OnPress, value, actorId);
					m_bMovementFlagRight = true;
				}
				else if(value==0.f)
				{
					if(m_bMovementFlagRight)
					{
						pVehicle->OnAction(eVAI_StrafeRight, eAAM_OnRelease, 0.f, actorId);
						m_bMovementFlagRight = false;
					}
					else if(m_bMovementFlagLeft)
					{
						pVehicle->OnAction(eVAI_StrafeLeft, eAAM_OnRelease, 0.f, actorId);
						m_bMovementFlagLeft = false;
					}
				}
				else//value<0
				{
					pVehicle->OnAction(eVAI_StrafeLeft, eAAM_OnPress, -value, actorId);
					m_bMovementFlagLeft = true;
				}
			}
			else
			{
				if(value>0.f)
				{
					pVehicle->OnAction(eVAI_TurnRight, eAAM_OnPress, value, actorId);
					m_bMovementFlagRight = true;
				}
				else if(value==0.f)
				{
					if(m_bMovementFlagRight)
					{
						pVehicle->OnAction(eVAI_TurnRight, eAAM_OnRelease, 0.f, actorId);
						m_bMovementFlagRight = false;
					}
					else if(m_bMovementFlagLeft)
					{
						pVehicle->OnAction(eVAI_TurnLeft, eAAM_OnRelease, 0.f, actorId);
						m_bMovementFlagLeft = false;
					}
				}
				else//value<0
				{
					pVehicle->OnAction(eVAI_TurnLeft, eAAM_OnPress, -value, actorId);
					m_bMovementFlagLeft = true;
				}
			}
			break;
		}
  case (eVAI_XIMoveY):
		{
			EVehicleActionIds eForward = eVAI_MoveForward;
			EVehicleActionIds eBack = eVAI_MoveBack;
			if(!strcmp("Asian_helicopter",pVehicle->GetEntity()->GetClass()->GetName()))
			{
				eForward = eVAI_MoveUp;
				eBack = eVAI_MoveDown;
			}

			if(value>0.f)
			{
				pVehicle->OnAction(eForward, eAAM_OnPress, value, actorId);
				m_bMovementFlagForward = true;
			}
			else if(value==0.f)
			{
				if(m_bMovementFlagForward)
				{
					pVehicle->OnAction(eForward, eAAM_OnRelease, 0.f, actorId);
					m_bMovementFlagForward = false;
				}
				else if(m_bMovementFlagBack)
				{
					pVehicle->OnAction(eBack, eAAM_OnRelease, 0.f, actorId);
					m_bMovementFlagBack = false;
				}
			}			
			else//value<0.f
			{
				pVehicle->OnAction(eBack, eAAM_OnPress, -value, actorId);
				m_bMovementFlagBack = true;
			}
      break;
		}
  case (eVAI_XIRotateYaw):
		{
			IVehicleMovement *pMovement = pVehicle->GetMovement();
			if(pMovement && pMovement->GetMovementType() == IVehicleMovement::eVMT_Air && pVehicle->IsPlayerDriving())
			{
				pVehicle->OnAction(eVAI_RotateYaw, eAAM_OnPress, value, actorId);
			}
			else
			{
				m_xiRotation.x = (5.0f*value)*(5.0f*value)*value;
			}
      break;
		}
  case (eVAI_XIRotatePitch):
		{
			IVehicleMovement *pMovement = pVehicle->GetMovement();
			if(pMovement && pMovement->GetMovementType() == IVehicleMovement::eVMT_Air && pVehicle->IsPlayerDriving())
			{
				pVehicle->OnAction(eVAI_RotatePitch, eAAM_OnPress, g_pGameCVars->cl_invertController ? -value : value, actorId);
			}
			else
			{
				m_xiRotation.y = (3.5f*value)*(3.5f*value)*(-value);
				if(g_pGameCVars->cl_invertController)
					m_xiRotation.y*=-1;
			}
      break;
		}
  case (eVAI_RotatePitch):
    {
      if (g_pGameCVars->cl_invertMouse)
        value *= -1.f;
      pVehicle->OnAction(ite->second, activationMode, value, actorId);
      break;
    }
  case (eVAI_TurnLeft):
    {
      if (activationMode == eAAM_OnPress || activationMode == eAAM_OnRelease)
        m_fLeftRight -= value*2.f - 1.f;
			m_fLeftRight = CLAMP(m_fLeftRight, -1.0f, 1.0f);
      pVehicle->OnAction(ite->second, activationMode, -m_fLeftRight, actorId);
      break;
    }
  case (eVAI_TurnRight):
    {
      if (activationMode == eAAM_OnPress || activationMode == eAAM_OnRelease)
        m_fLeftRight += value*2.f - 1.f;
			m_fLeftRight = CLAMP(m_fLeftRight, -1.0f, 1.0f);
      pVehicle->OnAction(ite->second, activationMode, m_fLeftRight, actorId);
      break;
    }  
  case (eVAI_MoveForward):
    {
      if (activationMode == eAAM_OnPress || activationMode == eAAM_OnRelease)
        m_fForwardBackward += value*2.f - 1.f;

			if(activationMode == eAAM_OnRelease)
				m_fForwardBackward = CLAMP(m_fForwardBackward, 0.0f, 1.0f);
			else
				m_fForwardBackward = CLAMP(m_fForwardBackward, -1.0f, 1.0f);
      pVehicle->OnAction(ite->second, activationMode, m_fForwardBackward, actorId);
      break;
    }
  case (eVAI_MoveBack):
    {
      if (activationMode == eAAM_OnPress || activationMode == eAAM_OnRelease)
        m_fForwardBackward -= value*2.f - 1.f;

			if(activationMode == eAAM_OnRelease)
				m_fForwardBackward = CLAMP(m_fForwardBackward, -1.0f, 0.0f);
			else
				m_fForwardBackward = CLAMP(m_fForwardBackward, -1.0f, 1.0f);
      pVehicle->OnAction(ite->second, activationMode, -m_fForwardBackward, actorId);
      break;
    }  
	case (eVAI_ZoomIn):
	case (eVAI_ZoomOut):
		if(SAFE_HUD_FUNC_RET(GetModalHUD()))
			break;
  default:
		pVehicle->OnAction(ite->second, activationMode, value, actorId);
    break;		
	}
}
Esempio n. 9
0
void CTornado::UpdateFlow()
{
	IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem();
	assert(pVehicleSystem);

	float frameTime(gEnv->pTimer->GetFrameTime());

	IPhysicalWorld *ppWorld = gEnv->pPhysicalWorld;

	Vec3 pos(GetEntity()->GetWorldPos());

	//first, check the entities in range
	m_nextEntitiesCheck -= frameTime;
	if (m_nextEntitiesCheck<0.0f)
	{
		m_nextEntitiesCheck = 1.0f;
		
		Vec3 radiusVec(m_radius,m_radius,0);
		
		IPhysicalEntity **ppList = NULL;

		int	numEnts = ppWorld->GetEntitiesInBox(pos-radiusVec,pos+radiusVec+Vec3(0,0,m_cloudHeight*0.5f),ppList,ent_sleeping_rigid|ent_rigid|ent_living);

		m_spinningEnts.clear();
		for (int i=0;i<numEnts;++i)
		{
			// add check for spectating players...
			EntityId id = ppWorld->GetPhysicalEntityId(ppList[i]);
			CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id));
			if(!pActor || !pActor->GetSpectatorMode())
			{
				m_spinningEnts.push_back(id);
			}
		}
		//OutputDistance();
	}

	//mess entities around
	for (size_t i=0;i<m_spinningEnts.size();++i)
	{
		IPhysicalEntity *ppEnt = ppWorld->GetPhysicalEntityById(m_spinningEnts[i]);
		if (ppEnt)
		{
			pe_status_pos spos;
			pe_status_dynamics sdyn;

			if (!ppEnt->GetStatus(&spos) || !ppEnt->GetStatus(&sdyn))
				continue;
		
			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(spos.pos,2.0f,ColorB(255,0,255,255));
						
			Vec3 delta(pos - spos.pos);
			delta.z = 0.0f;

			float dLen(delta.len());
			float forceMult(max(0.0f,(m_radius-dLen)/m_radius));

			if (dLen>0.001f)
				delta /= dLen;
			else
				delta.zero();

			Vec3 upVector(0,0,1);

			float spinImpulse(m_spinImpulse);
			float attractionImpulse(m_attractionImpulse);
			float upImpulse(m_upImpulse);

			if (ppEnt->GetType() == PE_LIVING)
			{
				upImpulse *= 0.75f;
				attractionImpulse *= 0.35f;
				spinImpulse *= 1.5f;
			}

			
			if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(m_spinningEnts[i]))
			{
				IVehicleMovement* pMovement = pVehicle->GetMovement();

				if (pMovement && pMovement->GetMovementType() == IVehicleMovement::eVMT_Air)
				{
					SVehicleMovementEventParams params;
					params.fValue = forceMult;
					pMovement->OnEvent(IVehicleMovement::eVME_Turbulence, params);
				}
			}

			Vec3 spinForce( (delta % upVector) * spinImpulse );
			Vec3 attractionForce(delta * attractionImpulse);
			Vec3 upForce(0,0,upImpulse);

			pe_action_impulse aimpulse;

			aimpulse.impulse = (spinForce + attractionForce + upForce) * (forceMult * sdyn.mass * frameTime);
			aimpulse.angImpulse = (upVector + (delta % upVector)) * (gf_PI * 0.33f * forceMult * sdyn.mass * frameTime);

			aimpulse.iApplyTime = 0;
			ppEnt->Action(&aimpulse);

			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(spos.pos,ColorB(255,0,255,255),spos.pos+aimpulse.impulse.GetNormalizedSafe(ZERO),ColorB(255,0,255,255));
		}
	}
}
Esempio n. 10
0
	virtual void ProcessEvent(EFlowEvent flowEvent, SActivationInfo* pActivationInfo)
	{
		if (flowEvent == eFE_Activate && IsPortActive(pActivationInfo, EIP_StartDriving))
		{
			IEntity* pEntity = pActivationInfo->pEntity;
			if(!pEntity)
				return;

			IVehicle* pVehicle;
			pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle( pEntity->GetId() );
			if(!pVehicle || pVehicle->IsDestroyed())
			{
				return;
			}

			IVehicleMovement* pMovement = pVehicle->GetMovement();
			if (!pMovement)
				return;

			CVehicleMovementBase* pMovementBase = StaticCast_CVehicleMovementBase(pMovement);
			if (!pMovementBase)
				return;

			IActor* pPlayer = g_pGame->GetIGameFramework()->GetClientActor();
			if (!pPlayer)
				return;

			const EntityId localPlayer = pPlayer->GetEntityId();
			if (pVehicle->GetSeatCount() == 0) // Don't need to remotely enter
			{
				pMovement->StartDriving(localPlayer);
			}
			else
			{
				pVehicle->EvictAllPassengers();

				IVehicleSeat* pSeat = pVehicle->GetSeatById(1);
				if (pSeat)
				{
					// Can't use remote entering to control otherwise if vehicle blows up, player dies
					//pSeat->EnterRemotely(localPlayer);

					pMovement->StartDriving(localPlayer);
					m_prevSeatLockStatus = pSeat->GetLockedStatus();
					pSeat->SetLocked(eVSLS_Locked);
				}
			}

			m_fDuration = GetPortFloat(pActivationInfo, EIP_Time);
			m_fSpeed = GetPortFloat(pActivationInfo, EIP_Speed);
			m_actInfo = *pActivationInfo;
			m_entityId = pEntity->GetId();
			
			SetActive(true);
		}
		else if (flowEvent == eFE_Update)
		{
			if (!m_bActive)
			{
				if (m_bNeedsCleanup)
				{
					Cleanup();
				}

				return;
			}

			IEntity* pEntity = pActivationInfo->pEntity;
			if(!pEntity)
			{
				SetActive(false);
				return;
			}

			IVehicle* pVehicle;
			pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle( pEntity->GetId() );
			if(!pVehicle || pVehicle->IsDestroyed())
			{
				SetActive(false);
				return;
			}

			const float curTime = gEnv->pTimer->GetFrameStartTime().GetSeconds();
			if ((curTime - m_fStartedTime) >= m_fDuration)
			{
				SetActive(false);

				ActivateOutput(pActivationInfo, EOP_TimeComplete, true);
			}
			else // Update every frame
			{
				IVehicleMovement* pMovement = pVehicle->GetMovement();
				if (pMovement)
				{
					// prevent full pedal being kept pressed, but give it a bit
					pMovement->OnAction(eVAI_MoveForward, eAAM_OnPress, 1.0f);
				}
			}
		}
	}