Exemple #1
0
bool SkillKill::IsKickedCarKill(CPlayer* pKicker, CPlayer* pTargetPlayer, EntityId vehicleId)
{
    if(pKicker->IsClient() && g_pGameCVars->g_mpKickableCars)
        {
            if (IVehicle* pKickedVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(vehicleId))
                {
                    if (CVehicleMovementBase* pMovement = StaticCast_CVehicleMovementBase(pKickedVehicle->GetMovement()))
                        {
                            if (const SVehicleMovementLargeObjectInfo* info = pMovement->GetLargeObjectInfo())
                                {
                                    if (info->kicker && info->kicker == pKicker->GetEntityId())
                                        {
                                            return true;
                                        }
                                }
                        }
                }
            else
                {
                    static const IEntityClass* pDestroyedVehicleClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("DestroyedVehicle");
                    CRY_ASSERT(pDestroyedVehicleClass);
                    IEntity* pEntity = gEnv->pEntitySystem->GetEntity(vehicleId);
                    return pEntity && pEntity->GetClass() == pDestroyedVehicleClass;
                }
        }

    return false;
}
float CGameRulesMPDamageHandling::ProcessActorVehicleCollision(IActor* victimActor, EntityId victimId, IVehicle* pVehicle, EntityId vehicleId, float damage, const CGameRules::SCollisionHitInfo& collisionHitInfo, EntityId& kickerId)
{
	kickerId = 0;
	if (g_pGameCVars->g_mpKickableCars)
	{
		if (CVehicleMovementBase* pMovement = StaticCast_CVehicleMovementBase(pVehicle->GetMovement()))
		{
			if (const SVehicleMovementLargeObjectInfo* info = pMovement->GetLargeObjectInfo())
			{
				kickerId = info->kicker;
			}
		}
	}
	return ProcessActorKickedVehicle(victimActor, victimId, kickerId, vehicleId, damage, collisionHitInfo);
}
void CVTOLVehicleManager::SetupMovement(EntityId entityId)
{
	IVehicle* pVehicle = m_pVehicleSystem->GetVehicle(entityId);
	if(pVehicle)
	{
		if (CVehicleMovementBase* pMovement = StaticCast_CVehicleMovementBase(pVehicle->GetMovement()))
		{
			pMovement->Reset();
			pMovement->SetRemotePilot(true);
			pMovement->StartDriving(0);
		}

		IGameObject* pGameObject = pVehicle->GetGameObject(); 

		pGameObject->SetUpdateSlotEnableCondition(pVehicle, IVehicle::eVUS_Always, eUEC_WithoutAI);
		pGameObject->SetUpdateSlotEnableCondition(pVehicle, IVehicle::eVUS_EnginePowered, eUEC_WithoutAI);
		pGameObject->EnableUpdateSlot(pVehicle, IVehicle::eVUS_EnginePowered);
		pGameObject->EnableUpdateSlot(pVehicle, IVehicle::eVUS_Always);
	}
}
//------------------------------------------------------------------------
void CVehicleViewSteer::Update(float dt)
{
	IEntity * pEntity = m_pVehicle->GetEntity();
	assert(pEntity);

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

	const SVehiclePhysicsStatus& dynStatus = pVehicleMovement->GetPhysicsStatus(CVehicleMovementBase::k_mainThread);

	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.

		{
			CRY_ASSERT(m_pVehicle);

			// Initialise sphere and direction.

			primitives::sphere	sphere;

			sphere.center	= m_lookAt;
			sphere.r			= g_CameraRadius;

			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();
}
	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);
				}
			}
		}
	}