コード例 #1
0
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);
	}
}
コード例 #2
0
ファイル: PlayerView.cpp プロジェクト: mrwonko/CrysisVR
void CPlayerView::ViewSpectatorTarget(SViewParams &viewParams)
{
	CActor* pTarget = (CActor*)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.stats_spectatorTarget);
	if(!pTarget)
		return;

	IVehicle* pVehicle = pTarget->GetLinkedVehicle();

	static float defaultOffset = 0.3f;
	static float viewHeight = 1.8f;

	Matrix34 worldTM = pTarget->GetEntity()->GetWorldTM();
	Vec3 worldPos = worldTM.GetTranslation();
	if(!pVehicle)
	{
		const SStanceInfo* stanceInfo = pTarget->GetStanceInfo(pTarget->GetStance());
		if(stanceInfo)
		{
			Interpolate(viewHeight, stanceInfo->viewOffset.z, 5.0f, viewParams.frameTime);
			worldPos.z += viewHeight + defaultOffset;
		}
		else
		{
			worldPos.z += 1.8f;
		}
	}
	else
	{
		// use vehicle pos/ori
		worldTM = pVehicle->GetEntity()->GetWorldTM();
		worldPos = pVehicle->GetEntity()->GetWorldPos();
		worldPos.z += 1.5f;
	}
	
	Ang3 worldAngles = Ang3::GetAnglesXYZ(Matrix33(worldTM));
	float distance = 3;

	// if freelook allowed, get orientation and distance from player entity
	if(g_pGameCVars->g_spectate_FixedOrientation == 0)
	{
		CPlayer* pThisPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId));
		if(!pThisPlayer)
			return;
		Matrix34 ownOrientation = pThisPlayer->GetEntity()->GetWorldTM();

		worldAngles += Ang3::GetAnglesXYZ(Matrix33(ownOrientation));
		distance = pThisPlayer->GetSpectatorZoom();
	}

	if(pVehicle)
	{
		distance *= 4.0f;

		// air vehicles need bigger distance
		if(pVehicle->GetMovement() && pVehicle->GetMovement()->GetMovementType() == IVehicleMovement::eVMT_Air)
			distance *= 2.0f;
	}

	Vec3 goal;
	goal.x = distance * cos(worldAngles.z + gf_PI*1.5f) + worldPos.x;
	goal.y = distance * sin(worldAngles.z - gf_PI/2.0f) + worldPos.y;

	AABB targetBounds;
	pTarget->GetEntity()->GetLocalBounds(targetBounds);
	goal.z = targetBounds.max.z;
	float offset = defaultOffset;
	if(pVehicle)
	{
		if(pVehicle->GetMovement() && pVehicle->GetMovement()->GetMovementType() == IVehicleMovement::eVMT_Air)
			offset = 3.0f;
		else
			offset = 1.0f;
	}
	goal.z += pTarget->GetEntity()->GetWorldPos().z + offset;

	// store / interpolate the offset, not the world pos (reduces percieved jitter in vehicles)
	static Vec3 viewOffset(goal-worldPos);
	static Vec3 camPos(goal);
	static Vec3 entPos(worldPos);
	static EntityId lastSpectatorTarget(m_in.stats_spectatorTarget);

	// do a ray cast to check for camera intersection
	static ray_hit hit;	
	IPhysicalEntity* pSkipEntities[10];
	int nSkip = 0;
	if(pVehicle)
	{
		// vehicle drivers don't seem to have current items, so need to add the vehicle itself here
		nSkip = pVehicle->GetSkipEntities(pSkipEntities, 10);
	}
	else
	{
		IItem* pItem = pTarget->GetCurrentItem();
		if (pItem)
		{
			CWeapon* pWeapon = (CWeapon*)pItem->GetIWeapon();
			if (pWeapon)
				nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10);
		}
	}

	static float minDist = 0.4f;	// how close we're allowed to get to the target
	static float wallSafeDistance = 0.3f; // how far to keep camera from walls

	Vec3 dir = goal - worldPos;
	primitives::sphere sphere;
	sphere.center = worldPos;
	sphere.r = wallSafeDistance;

	geom_contact *pContact = 0;          
	float hitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, dir, 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, nSkip);

	// even when we have contact, keep the camera the same height above the target
	float minHeightDiff = dir.z;

	if(hitDist > 0 && pContact)
	{
		goal = worldPos + (hitDist * dir.GetNormalizedSafe());
		
		if(goal.z - worldPos.z < minHeightDiff)
		{
			// can't move the camera far enough away from the player in this direction. Try moving it directly up a bit
			int numHits = 0;
			sphere.center = goal;

			// (move back just slightly to avoid colliding with the wall we've already found...)
			sphere.center -= dir.GetNormalizedSafe() * 0.05f;

			float newHitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, Vec3(0,0,minHeightDiff), 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, nSkip);

			float raiseDist = minHeightDiff - (goal.z - worldPos.z) - wallSafeDistance;
			if(newHitDist != 0)
			{
				raiseDist = MIN(minHeightDiff, newHitDist);
			}
			
			raiseDist = MAX(0.0f, raiseDist);
			
			goal.z += raiseDist;
			worldPos.z += raiseDist*0.8f;
		}
	}

	int thisFrameId = gEnv->pRenderer->GetFrameID();
	static int frameNo(thisFrameId);
	if(thisFrameId - frameNo > 5)
	{
		// reset positions
		viewOffset = goal - worldPos;
		entPos = worldPos;
		camPos = goal;
	}
	if(lastSpectatorTarget != m_in.stats_spectatorTarget)
	{
		viewOffset = goal - worldPos;
		entPos = worldPos;
		camPos = goal;
		lastSpectatorTarget = m_in.stats_spectatorTarget;
	}
	frameNo = thisFrameId;

	static float interpSpeed = 5.0f;
	static float interpSpeed2 = 5.0f;
	static float interpSpeed3 = 8.0f;

	if(pVehicle)
	{
		Interpolate(viewOffset, goal-worldPos, interpSpeed, viewParams.frameTime);
		entPos = worldPos;
		viewParams.position = worldPos + viewOffset;
		camPos = viewParams.position;
	}
	else
	{
		Vec3 camPosChange = goal - camPos;
		Vec3 entPosChange = worldPos - entPos;

		if(camPosChange.GetLengthSquared() > 100.0f)
			camPos = goal;
		if(entPosChange.GetLengthSquared() > 100.0f)
			entPos = worldPos;

		Interpolate(camPos, goal, interpSpeed2, viewParams.frameTime);
		Interpolate(entPos, worldPos, interpSpeed3, viewParams.frameTime);
		viewParams.position = camPos;
	}

	Matrix33 rotation = Matrix33::CreateRotationVDir((entPos - viewParams.position).GetNormalizedSafe());
	viewParams.rotation = GetQuatFromMat33(rotation);	
	m_io.bUsePivot = true;
	m_io.stats_bobCycle = 0.0;
}
コード例 #3
0
void CVTOLVehicleManager::Update(float frameTime)
{
	// Update logic goes here
	if(CGameRules* pGameRules = g_pGame->GetGameRules())
	{
		CGameRules::TPlayers players;
		pGameRules->GetPlayers(players);

		for (TVTOLList::iterator iter=m_vtolList.begin(), end=m_vtolList.end(); iter!=end; ++iter)
		{
			SVTOLInfo& info = iter->second;
			IVehicle* pVehicle = m_pVehicleSystem->GetVehicle( info.entityId );
			if(pVehicle)
			{
				info.stateTime += frameTime;

				// Find difference in rotation
				Quat newRotation = pVehicle->GetEntity()->GetWorldRotation();
				newRotation.Normalize();
				Quat rotationDifference = newRotation*info.location.q.GetInverted();
				rotationDifference.Normalize();

				// Store new rotation + position
				info.location.q = newRotation;
				info.location.t = pVehicle->GetEntity()->GetWorldPos();

				if(info.state==EVS_Normal)
				{
					pVehicle->NeedsUpdate(IVehicle::eVUF_AwakePhysics);

					if(CVehicleMovementMPVTOL* pMovement = static_cast<CVehicleMovementMPVTOL*>(pVehicle->GetMovement()))
					{
						const uint8 pathComplete = pMovement->GetPathComplete();
						if(pathComplete==1)
						{
							if(CMPPathFollowingManager* pMPPathFollowingManager = g_pGame->GetGameRules()->GetMPPathFollowingManager())
							{
								pMPPathFollowingManager->NotifyListenersOfPathCompletion(info.entityId);
							}
							pMovement->SetPathCompleteNotified();
						}
					}
				}

				// Check status
				if(info.state==EVS_Normal && pVehicle->GetDamageRatio() >= 1.f)
				{
					if(gEnv->bServer)
					{
						DestructionDamageRatioReached(pVehicle, info, frameTime);
					}
				}
				else if(info.state == EVS_Invisible)
				{
					if(info.stateTime > g_pGameCVars->g_VTOLRespawnTime)
					{
						RespawnVTOL(pVehicle, info);
					}
				}

				//Process players
				TPlayerList& currentPlayerList = info.playersInside;
				TPlayerList oldPlayerList = currentPlayerList;
				currentPlayerList.clear();

				CGameRules::TPlayers::iterator iterPlayer = players.begin();
				const CGameRules::TPlayers::const_iterator endPlayer = players.end();
				while(iterPlayer != endPlayer)
				{
					// Adding safeguard to protect against cases where user alt-f4 quits program. 
					UpdateEntityInVTOL(info, *iterPlayer); 
					++iterPlayer;
				}
				
				//Find out who has been inside since the last update, who has just entered, and who has left
				TPlayerStatusList playerStatusList;
				int currentId;
				for(unsigned int prev = 0; prev < currentPlayerList.size(); ++prev)
				{
					currentId = currentPlayerList[prev];
					bool found = false;
					TPlayerList::iterator oldIter = oldPlayerList.begin();
					TPlayerList::iterator oldEnd = oldPlayerList.end();
					while(oldIter != oldEnd)
					{
						if(currentId == *oldIter) //In both lists so still inside
						{
							found = true;
							playerStatusList.push_back( TPlayerStatus(currentId, E_PEVS_StillInside) );
							oldPlayerList.erase(oldIter);
							break;
						}
						++oldIter;
					}
					if(!found) //Only in current list so entered
					{
						playerStatusList.push_back( TPlayerStatus(currentId, E_PEVS_Entered) );
					}
				}
				//Those remaining in old list have exited
				for(unsigned int old = 0; old < oldPlayerList.size(); ++old) 
				{
					playerStatusList.push_back( TPlayerStatus(oldPlayerList[old], E_PEVS_Exited) );
				}

				//Act based on current state
				TPlayerStatusList::iterator statusIter = playerStatusList.begin();
				TPlayerStatusList::iterator statusEnd = playerStatusList.end();
				while(statusIter != statusEnd)
				{
					switch(statusIter->second)
					{
					case E_PEVS_Entered:
						{
							OnPlayerEntered(statusIter->first);
						}
						break;
					case E_PEVS_Exited:
						{
							OnPlayerExited(statusIter->first);
						}
						break;
					}
					++statusIter;
				}

				UpdateRotationOfInternalPlayers(info, playerStatusList, rotationDifference);
			}
		}
	}
}
コード例 #4
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);
				}
			}
		}
	}