Esempio n. 1
0
	void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
	{
		switch (event)
		{
		case eFE_Initialize:
			{
				CGameRules* pGameRules = g_pGame->GetGameRules();
				if(pGameRules)
					pGameRules->AddGameRulesListener(this);

				CPlayer* pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor());
				if(pPlayer)
					m_localPlayerSpectatorMode = pPlayer->GetSpectatorMode();

				m_actInfo = *pActInfo;
			}
			break;
		case eFE_Activate:
			break;
		case eFE_Update:
			{
				CPlayer* pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor());
				if(!pPlayer)
					return;

				// first check: tac weapons trigger endgamenear / endgameinvalid
				if(m_MDList.empty() && m_endGameNear)
				{
					// if less than 3 min remaining don't return to normal
					bool cancel = true;
					if(g_pGame && g_pGame->GetGameRules() && g_pGame->GetGameRules()->IsTimeLimited() && m_timeRemainingTriggered)
					{
						float timeRemaining = g_pGame->GetGameRules()->GetRemainingGameTime();
						if(timeRemaining < GetPortFloat(pActInfo, EIP_GameEndTime) )
							cancel = false;
					}

					if(cancel)
					{
						if(g_pGame->GetCVars()->i_debug_mp_flowgraph != 0)
						{
							CryLog("MP flowgraph: EndGameInvalid");
						}
						ActivateOutput(&m_actInfo, EOP_EndGameInvalid, true);
						m_endGameNear = false;
					}
				}
				else if(!m_MDList.empty())
				{
					// go through the list of tac/sing weapons and check if they are still present
					std::list<EntityId>::iterator next;
					std::list<EntityId>::iterator it = m_MDList.begin();
					for(; it != m_MDList.end(); it = next)
					{
						next = it; ++next;
						if(gEnv->pEntitySystem->GetEntity(*it))
						{
							// entity exists so trigger loud music if not already done
							if(!m_endGameNear)
							{
								if(g_pGame->GetCVars()->i_debug_mp_flowgraph != 0)
								{
									CryLog("--MP flowgraph: EndGameNear");
								}
								ActivateOutput(&m_actInfo, EOP_EndGameNear, true);
								m_endGameNear = true;
							}

							// in the case of tanks, entity isn't removed for quite some time after destruction.
							//	Check vehicle health directly here...
							IVehicle* pVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(*it);
							if(pVehicle && pVehicle->IsDestroyed())
							{
								m_MDList.erase(it);
							}
						}
						else
						{
							// entity no longer exists - remove from list.
 							m_MDList.erase(it);
						}
					}
				}

				// get the remaining time from game rules
				if(!m_timeRemainingTriggered && g_pGame->GetGameRules() && g_pGame->GetGameRules()->IsTimeLimited() && pPlayer->GetSpectatorMode() == 0 && !m_endGameNear)
				{
					float timeRemaining = g_pGame->GetGameRules()->GetRemainingGameTime();
					if(timeRemaining < GetPortFloat(pActInfo, EIP_GameEndTime) )
					{
						if(g_pGame->GetCVars()->i_debug_mp_flowgraph != 0)
						{
							CryLog("--MP flowgraph: EndGameNear");
						}
						ActivateOutput(&m_actInfo, EOP_EndGameNear, timeRemaining);
						m_timeRemainingTriggered = true;
						m_endGameNear = true;
					}
				}

				// also check whether the local player is in game yet
  				if(pPlayer->GetSpectatorMode() == 0 && m_localPlayerSpectatorMode != 0)
  				{
						if(g_pGame->GetCVars()->i_debug_mp_flowgraph != 0)
						{
							CryLog("--MP flowgraph: EnteredGame");
						}
  					ActivateOutput(&m_actInfo, EOP_EnteredGame, true);
  					m_localPlayerSpectatorMode = pPlayer->GetSpectatorMode();
  				}
			}
			break;
		}
	}
Esempio n. 2
0
//-----------------------------------------------------------------------------
void CHomingMissile::UpdateControlledMissile(float frameTime)
{
	bool isServer = gEnv->bServer;
	bool isClient = gEnv->IsClient();

	CActor *pClientActor=0;

	if(gEnv->IsClient())
		pClientActor=static_cast<CActor *>(g_pGame->GetIGameFramework()->GetClientActor());

	bool isOwner = ((!m_ownerId && isServer) || (isClient && pClientActor && (pClientActor->GetEntityId() == m_ownerId) && pClientActor->IsPlayer()));

	IRenderer *pRenderer = gEnv->pRenderer;
	IRenderAuxGeom *pGeom = pRenderer->GetIRenderAuxGeom();
	float color[4] = {1,1,1,1};
	const static float step = 15.f;
	float y = 20.f;

	bool bDebug = g_pGameCVars->i_debug_projectiles > 0;

	if(isOwner || isServer)
	{
		//If there's a target, follow the target
		if(isServer)
		{
			if(m_targetId)
			{
				if(m_lockedTimer>0.0f)
					m_lockedTimer=m_lockedTimer-frameTime;
				else
				{
					// If we are here, there's a target
					IEntity *pTarget = gEnv->pEntitySystem->GetEntity(m_targetId);

					if(pTarget)
					{
						AABB box;
						pTarget->GetWorldBounds(box);
						Vec3 finalDes = box.GetCenter();
						SetDestination(finalDes);
						//SetDestination( box.GetCenter() );

						if(bDebug)
							pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Target Entity: %s", pTarget->GetName());
					}

					m_lockedTimer+=0.05f;
				}
			}
			else if(m_autoControlled)
				return;
		}

		if(m_controlled && !m_autoControlled && isOwner && !m_targetId)
		{
			//Check if the weapon is still selected
			CWeapon *pWeapon = GetWeapon();

			if(!pWeapon || !pWeapon->IsSelected())
				return;

			if(m_controlledTimer>0.0f)
				m_controlledTimer=m_controlledTimer-frameTime;
			else if(pClientActor && pClientActor->IsPlayer()) 	//Follow the crosshair
			{
				if(IMovementController *pMC=pClientActor->GetMovementController())
				{
					Vec3 eyePos(ZERO);
					Vec3 eyeDir(ZERO);

					IVehicle *pVehicle = pClientActor->GetLinkedVehicle();

					if(!pVehicle)
					{
						SMovementState state;
						pMC->GetMovementState(state);

						eyePos = state.eyePosition;
						eyeDir = state.eyeDirection;
					}
					else
					{
						SViewParams viewParams;
						pVehicle->UpdateView(viewParams, pClientActor->GetEntityId());

						eyePos = viewParams.position;
						eyeDir = viewParams.rotation * Vec3(0,1,0);
						//eyeDir = (viewParams.targetPos - viewParams.position).GetNormalizedSafe();
					}

					static const int objTypes = ent_all;
					static const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (7 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit);

					IPhysicalWorld *pWorld = gEnv->pPhysicalWorld;
					static IPhysicalEntity *pSkipEnts[10];
					int numSkip = CSingle::GetSkipEntities(pWeapon, pSkipEnts, 10);

					ray_hit hit;
					int hits = 0;

					hits = pWorld->RayWorldIntersection(eyePos + 1.5f*eyeDir, eyeDir*m_maxTargetDistance, objTypes, flags, &hit, 1, pSkipEnts, numSkip);

					DestinationParams params;

					if(hits)
						params.pt=hit.pt;
					else
						params.pt=(eyePos+m_maxTargetDistance*eyeDir);	//Some point in the sky...

					GetGameObject()->InvokeRMI(SvRequestDestination(), params, eRMI_ToServer);

					if(bDebug)
					{
						pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "PlayerView eye direction: %.3f %.3f %.3f", eyeDir.x, eyeDir.y, eyeDir.z);
						pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "PlayerView Target: %.3f %.3f %.3f", hit.pt.x, hit.pt.y, hit.pt.z);
						pRenderer->GetIRenderAuxGeom()->DrawCone(m_destination, Vec3(0,0,-1), 2.5f, 7.f, ColorB(255,0,0,255));
					}
				}

				m_controlledTimer+=0.0f;
			}
		}
	}

	//This code is shared by both modes above (auto and controlled)
	if(!m_destination.IsZero())
	{
		pe_status_dynamics status;

		if(!GetEntity()->GetPhysics()->GetStatus(&status))
		{
			CryLogAlways("couldn't get physics status!");
			return;
		}

		pe_status_pos pos;

		if(!GetEntity()->GetPhysics()->GetStatus(&pos))
		{
			CryLogAlways("couldn't get physics pos!");
			return;
		}

		float currentSpeed = status.v.len();

		if(currentSpeed>0.001f)
		{
			Vec3 currentVel = status.v;
			Vec3 currentPos = pos.pos;
			Vec3 goalDir(ZERO);

			assert(!_isnan(currentSpeed));
			assert(!_isnan(currentVel.x) && !_isnan(currentVel.y) && !_isnan(currentVel.z));

			//Just a security check
			if((currentPos-m_destination).len2()<(m_detonationRadius*m_detonationRadius))
			{
				Explode(true, true, m_destination, -currentVel.normalized(), currentVel, m_targetId);

				return;
			}

			goalDir = m_destination - currentPos;
			goalDir.Normalize();

			//Turn more slowly...
			currentVel.Normalize();

			if(bDebug)
			{

				pRenderer->Draw2dLabel(50,55,2.0f,color,false, "  Destination: %.3f, %.3f, %.3f",m_destination.x,m_destination.y,m_destination.z);
				pRenderer->Draw2dLabel(50,80,2.0f,color,false, "  Current Dir: %.3f, %.3f, %.3f",currentVel.x,currentVel.y,currentVel.z);
				pRenderer->Draw2dLabel(50,105,2.0f,color,false,"  Goal    Dir: %.3f, %.3f, %.3f",goalDir.x,goalDir.y,goalDir.z);
			}

			float cosine = currentVel.Dot(goalDir);
			cosine = CLAMP(cosine,-1.0f,1.0f);
			float totalAngle = RAD2DEG(cry_acosf(cosine));

			assert(totalAngle>=0);

			if(cosine<0.99)
			{
				float maxAngle = m_turnSpeed*frameTime;

				if(maxAngle>totalAngle)
					maxAngle=totalAngle;

				float t=(maxAngle/totalAngle)*m_lazyness;

				assert(t>=0.0 && t<=1.0);

				goalDir = Vec3::CreateSlerp(currentVel, goalDir, t);
				goalDir.Normalize();
			}

			if(bDebug)
				pRenderer->Draw2dLabel(50,180,2.0f,color,false,"Corrected Dir: %.3f, %.3f, %.3f",goalDir.x,goalDir.y,goalDir.z);

			pe_action_set_velocity action;
			action.v = goalDir * currentSpeed;
			GetEntity()->GetPhysics()->Action(&action);
		}
	}
}
Esempio n. 3
0
void CPlayerRotation::Process(IItem* pCurrentItem, const SActorFrameMovementParams& movement, const SAimAccelerationParams& verticalAcceleration, float frameTime)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	// reset to the new impulse.
	m_angularImpulseDelta = m_angularImpulse;

	m_deltaAngles = movement.deltaAngles;

	PR_CHECKQNAN_FLT(m_deltaAngles);

	// Store the previous rotation to get the correct rotation for linked actors.
	const Quat previousBaseQuat = m_baseQuat;
	const Quat previousViewQuat = m_viewQuat;

	ProcessForcedLookDirection(m_viewQuatFinal, frameTime);

	ProcessAngularImpulses( frameTime );

	ProcessLeanAndPeek( movement );

	ProcessNormalRoll( frameTime );

	bool shouldProcessTargetAssistance = ShouldProcessTargetAssistance();
	if (shouldProcessTargetAssistance)
	{
		ProcessTargetAssistance( pCurrentItem );
	}

#if TALOS
	if(stricmp(g_pGameCVars->pl_talos->GetString(), m_player.GetEntity()->GetName()) == 0)
	{
		IMovementController* pMovementController = m_player.GetMovementController();
		CRY_ASSERT(pMovementController);
		SMovementState moveState;
		pMovementController->GetMovementState(moveState);

		Vec3 playerView[4] =
		{
			m_viewQuat.GetColumn0(), // Right
			m_viewQuat.GetColumn1(), // Forward
			m_viewQuat.GetColumn2(), // Up
			moveState.eyePosition    // Pos
		};

		GetTalosInput(this, m_player, m_deltaAngles.x, m_deltaAngles.z, playerView, frameTime);
	}
#endif

	float minAngle,maxAngle;
	GetStanceAngleLimits(verticalAcceleration, pCurrentItem, minAngle, maxAngle);
	ClampAngles( minAngle, maxAngle );

	ProcessNormal( frameTime );

	if(shouldProcessTargetAssistance)
	{
		IVehicle* pVehicle = m_player.GetLinkedVehicle();
		if (pVehicle && GetCurrentItem(true))
		{
			if (m_deltaAngles.x!=0.f)
				pVehicle->OnAction(eVAI_RotatePitchAimAssist, eAAM_Always, m_deltaAngles.x, m_player.GetEntity()->GetId());
			if (m_deltaAngles.z!=0.f)
				pVehicle->OnAction(eVAI_RotateYawAimAssist, eAAM_Always, m_deltaAngles.z, m_player.GetEntity()->GetId());
		}
	}

	//update freelook when linked to an entity
	ProcessLinkedState(m_player.m_linkStats, previousBaseQuat, previousViewQuat);

	//Recoil/Zoom sway offset for local player
	ProcessFinalViewEffects( minAngle, maxAngle );

	m_frameViewAnglesOffset.Set(0.0f, 0.0f, 0.0f);
	m_forceLookVector.zero();
	m_externalAngles.Set(0.f, 0.f, 0.f);

	NormalizeQuats();
}
Esempio n. 4
0
//---------------------------------------------------------------------------
void CVehicleWeapon::CheckForFriendlyAI(float frameTime)
{
	CActor* pOwner = GetOwnerActor();

	if(pOwner && m_pVehicle && pOwner->IsPlayer() && !gEnv->bMultiplayer)
	{
		m_timeToUpdate-=frameTime;
		if(m_timeToUpdate>0.0f)
			return;

		m_timeToUpdate = 0.15f;


		if(IMovementController* pMC = pOwner->GetMovementController())
		{
			SMovementState info;
			pMC->GetMovementState(info);

			LowerWeapon(false);

			//Try with boxes first
			bool success = false;			
			
			//Try ray hit
			if(!success)
			{
				ray_hit rayhit;
				IPhysicalEntity* pSkipEnts[10];
				int nSkip = CSingle::GetSkipEntities(this, pSkipEnts, 10);	

				int intersect = gEnv->pPhysicalWorld->RayWorldIntersection(info.weaponPosition, info.aimDirection * 150.0f, ent_all,
					rwi_stop_at_pierceable|rwi_colltype_any, &rayhit, 1, pSkipEnts, nSkip);

				IEntity* pLookAtEntity = NULL;

				if(intersect && rayhit.pCollider)
					pLookAtEntity = m_pEntitySystem->GetEntityFromPhysics(rayhit.pCollider);

				if(pLookAtEntity && pLookAtEntity->GetAI() && pOwner->GetEntity() && pLookAtEntity->GetId()!=GetEntityId())
				{
					bool bFriendlyVehicle = false;
					if( pLookAtEntity && pLookAtEntity->GetId() )
					{
						IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(pLookAtEntity->GetId());
						if ( pVehicle )
						{
							if ( pOwner->GetEntity() && pVehicle->HasFriendlyPassenger( pOwner->GetEntity() ) )
								bFriendlyVehicle = true;
						}				
					}

					if(bFriendlyVehicle||!pLookAtEntity->GetAI()->IsHostile(pOwner->GetEntity()->GetAI(),false))
					{
						LowerWeapon(true);
						StopFire();//Just in case

						success = true;
						m_pLookAtEnemy = NULL;
					}	
				}
				else if(pLookAtEntity)
				{
					//Special case (Animated objects), check for script table value "bFriendly"
					SmartScriptTable props;
					IScriptTable* pScriptTable = pLookAtEntity->GetScriptTable();
					if(!pScriptTable || !pScriptTable->GetValue("Properties", props))
						return;

					int isFriendly = 0;
					if(props->GetValue("bNoFriendlyFire", isFriendly) && isFriendly!=0)
					{
						LowerWeapon(true);
						StopFire();//Just in case

						success = true;
						m_pLookAtEnemy = NULL;
					}
					
				}
				else if(!pLookAtEntity)
					m_pLookAtEnemy = NULL;
			}

		}
	}		
}