예제 #1
0
bool CBaseGrabHandler::StartDrop()
{
	IEntity *pGrab = gEnv->pEntitySystem->GetEntity(m_grabStats.grabId);
	IPhysicalEntity *pGrabPhys = pGrab ? pGrab->GetPhysics() : NULL;

	if (pGrabPhys && m_grabStats.throwVector.len2()>0.01f)
	{	
		pe_action_set_velocity asv;
		asv.v = m_grabStats.throwVector;

		asv.w.x = -1.0f + (cry_rand()/(float)RAND_MAX*(float)(2.0f));
		asv.w.y = -1.0f + (cry_rand()/(float)RAND_MAX*(float)(2.0f));
		asv.w.z = -1.0f + (cry_rand()/(float)RAND_MAX*(float)(2.0f));
		asv.w.NormalizeSafe();
		asv.w *= 2.0f;

		pGrabPhys->Action(&asv);
	}

	if (m_grabStats.grabId>0)
	{
		m_grabStats.dropId = m_grabStats.grabId;
		m_grabStats.resetFlagsDelay = 1.0f;

		m_pActor->CreateScriptEvent("droppedObject",(float)m_grabStats.grabId);

		if (pGrab) DisableGrabbedAnimatedCharacter (false);
	}

	m_grabStats.Reset();

	return true;
}
//------------------------------------------------------------------------
void CVehicleMovementHelicopter::OnEvent(EVehicleMovementEvent event, const SVehicleMovementEventParams &params)
{
	CVehicleMovementBase::OnEvent(event, params);

	if(event == eVME_DamageSteering)
	{
		float newSteeringDamage = (((float(cry_rand()) / float(RAND_MAX)) * 2.5f) + 0.5f);
		m_steeringDamage = max(m_steeringDamage, newSteeringDamage);
	}
	else if(event == eVME_Repair)
	{
		m_steeringDamage = min(m_steeringDamage, params.fValue);

		// bit workaround - we never get a repair message for the last bit (as the damage level hasn't changed).
		//	However, the helicopter only ever sends 1.0 or 0.0 to here...
		if(params.fValue < 0.25)
		{
			m_damageActual = 0.0f;
			m_damage = 0.0f;
		}
	}
	else if(event == eVME_GroundCollision)
	{
		const float stopOver = 1.0f;

		m_isTouchingGround = true;
		m_noHoveringTimer = max(stopOver, m_noHoveringTimer);
	}
	else if(event == eVME_Damage)
	{
		const float stopOver = 1.0f;

		m_noHoveringTimer = max(stopOver, m_noHoveringTimer);
		m_damage = params.fValue;
	}
	else if(event == eVME_WarmUpEngine)
	{
		m_enginePower = m_enginePowerMax;
	}
	else if(event == eVME_PlayerSwitchView)
	{
		if(params.fValue == 1.0f)
		{
			m_desiredRoll = 0.0f;
			m_rotateTarget.y = 0.0f;
		}
	}
	else if(event == eVME_Turbulence)
	{
		m_turbulence = max(m_turbulence, params.fValue);
	}
}
//static-------------------------------------------------------
void CAreaAnnouncer::CmdPlay(IConsoleCmdArgs* pCmdArgs)
{
	CGameRules *pGameRules = g_pGame->GetGameRules();
	CAreaAnnouncer* pAA = pGameRules->GetAreaAnnouncer();

	if(pAA->m_areaList.size() > 0)
	{
		int randA = cry_rand() % pAA->m_areaList.size();

		const EntityId clientId = gEnv->pGame->GetIGameFramework()->GetClientActorId();
		CAudioSignalPlayer::JustPlay(pAA->m_areaList[randA].m_signal[pAA->GetAreaAnnouncerTeamIndex(clientId)]);

		CryLogAlways("Playing - %s_%d", pAA->m_areaList[randA].m_name, pAA->GetAreaAnnouncerTeamIndex(clientId));
	}
	else
	{
		CryLogAlways("Unable to play because there aren't any areas!");
	}
}
예제 #4
0
void CFrogBoid::Think( float dt,SBoidContext &bc )
{
	Vec3 flockHeading(0,0,0);

	m_accel(0,0,0);

	bool bScaredJump = false;
	//////////////////////////////////////////////////////////////////////////
	// Scare points also scare chicken off.
	//////////////////////////////////////////////////////////////////////////
	if (bc.scareRatio > 0)
	{
		float sqrScareDist = m_pos.GetSquaredDistance(bc.scarePoint);
		if (sqrScareDist < bc.scareRadius*bc.scareRadius)
		{
			bScaredJump = true;
		}
	}
	//////////////////////////////////////////////////////////////////////////

	m_fTimeToNextJump -= dt;
	if (m_onGround)
	{
		float fScareDist = MAX_FROG_SCARE_DISTANCE;
		float sqrPlayerDist = m_pos.GetSquaredDistance(bc.playerPos);
		if (m_fTimeToNextJump <= 0 || sqrPlayerDist < fScareDist*fScareDist || bScaredJump)
		{
			PlaySound(FROG_SOUND_JUMP);
			PlayAnimationId( FROG_JUMP_ANIM,false,0 );
			
			m_fTimeToNextJump = 2.0f + cry_frand()*5.0f; // about every 5-6 second.
			//m_fTimeToNextJump = 0;

			// Scared by player or random jump.
			m_onGround = false;
			m_heading = m_pos - bc.playerPos;
			
			if (bScaredJump)
			{
				// Jump from scare point.
				m_heading = Vec3(m_pos - bc.scarePoint).GetNormalized();
			}
			else if (sqrPlayerDist < fScareDist*fScareDist)
			{
				// Jump from player.
				m_heading = Vec3(m_pos - bc.playerPos).GetNormalized();
			}
			else
			{
				if (m_heading != Vec3(0,0,0))
				{
					m_heading = m_heading.GetNormalized();
				}
				else
					m_heading = Vec3(Boid::Frand(),Boid::Frand(),Boid::Frand()).GetNormalized();

				if (m_pos.GetSquaredDistance(bc.flockPos) > bc.fSpawnRadius)
				{
					// If we are too far from spawn radius, jump back.
					Vec3 jumpToOrigin = Vec3(	bc.flockPos.x+Boid::Frand()*bc.fSpawnRadius,bc.flockPos.y+Boid::Frand()*bc.fSpawnRadius,bc.flockPos.z+Boid::Frand()*bc.fSpawnRadius );
					m_heading = Vec3(jumpToOrigin-m_pos).GetNormalized();
				}
			}
			
			m_heading += Vec3(Boid::Frand()*0.4f,Boid::Frand()*0.4f,0 );
			m_heading.Normalize();
			m_heading.z = 0.5f + (Boid::Frand()+1.0f)*0.3f;
			m_heading.Normalize();

			if (bc.avoidObstacles)
			{
				int retries = 4;
				bool bCollision;
				do 
				{
					bCollision = false;
					// Avoid obstacles & terrain.
					IPhysicalWorld *physWorld = bc.physics;

					Vec3 vPos = m_pos + Vec3(0,0,bc.fBoidRadius*0.5f);
					Vec3 vDir = m_heading*(bc.fBoidRadius*5) + Vec3(0,0,bc.fBoidRadius*1.0f);

					int objTypes = ent_all|ent_no_ondemand_activation;
					int flags = rwi_stop_at_pierceable|rwi_ignore_terrain_holes;
					ray_hit hit;
					int col = physWorld->RayWorldIntersection( vPos,vDir,objTypes,flags,&hit,1 );
					if (col != 0 && hit.dist > 0)
					{
						bCollision = true;
						m_heading = Vec3(Boid::Frand(),Boid::Frand(),0 ); // Pick some random jump vector.
						m_heading.Normalize();
						m_heading.z = 0.5f + (Boid::Frand()+1.0f)*0.3f;
						m_heading.Normalize();
					}
				} while (!bCollision && retries-- > 0);
			}

			m_speed = bc.MinSpeed + cry_frand()*(bc.MaxSpeed-bc.MinSpeed);
		}
	}

	bc.terrainZ = bc.engine->GetTerrainElevation(m_pos.x,m_pos.y) + bc.fBoidRadius*0.5f;

	float range = bc.MaxAttractDistance;

	Vec3 origin = bc.flockPos;

	if (bc.followPlayer)
	{
		origin = bc.playerPos;
	}

	// Keep in range.
	if (bc.followPlayer)
	{
		bool bChanged = false;
		if (m_pos.x < origin.x - range)
		{
			m_pos.x = origin.x + range;
			bChanged = true;
		}
		if (m_pos.y < origin.y - range)
		{
			m_pos.y = origin.y + range;
			bChanged = true;
		}
		if (m_pos.x > origin.x + range)
		{
			m_pos.x = origin.x - range;
			bChanged = true;
		}
		if (m_pos.y > origin.y + range)
		{
			m_pos.y = origin.y - range;
			bChanged = true;
		}
		if (bChanged)
			m_pos.z = bc.terrainZ = bc.engine->GetTerrainElevation(m_pos.x,m_pos.y) + bc.fBoidRadius*0.5f;
	}
	else
	{
	}

	if (!m_onGround)
	{
		m_accel.Set( 0,0,-10 );
	}

	if (m_pos.z < bc.terrainZ+0.001f)
	{
		// Land.
		m_pos.z = bc.terrainZ+0.001f;
		if (!m_onGround)
		{
			m_heading.z = 0;
			m_onGround = true;
			m_speed = 0;
			PlayAnimationId( FROG_IDLE_ANIM,true );
		}
	}

	// Do random idle sounds.
	if ((cry_rand()&0xFF) == 0)
		PlaySound(FROG_SOUND_IDLE);
}
예제 #5
0
void CChickenBoid::Think( float dt,SBoidContext &bc )
{
	Vec3 flockHeading(0,0,0);

	m_accel(0,0,0);
//	float height = m_pos.z - bc.terrainZ;

	if (m_bThrown)
	{
		m_accel.Set(0,0,-10.0f);
		//float z = bc.engine->GetTerrainElevation(m_pos.x,m_pos.y) + bc.fBoidRadius*0.5f;
		m_pos.z = bc.engine->GetTerrainElevation(m_pos.x,m_pos.y) + bc.fBoidRadius*0.5f;
		//pe_status_pos ppos;
		//m_pPhysics->GetStatus(&ppos);
		//if (m_pos.z < z)
		{
			m_physicsControlled = false;
			m_bThrown = false;
			m_heading.z = 0;
			if (m_heading.IsZero())
				m_heading = Vec3(1,0,0);
			m_heading.Normalize();
			m_accel.Set(0,0,0);
			m_speed = bc.MinSpeed;
			m_heading.z = 0;
		}
		return;
	}

	// Free will.
	// Continue accelerating in same dir untill target speed reached.
	// Try to maintain average speed of (maxspeed+minspeed)/2
	float targetSpeed = bc.MinSpeed;
	m_accel -= m_heading*(m_speed-targetSpeed)*0.4f;

	// Gaussian weight.
	m_accel.z = 0;

	m_bScared = false;

	if (bc.factorAlignment != 0)
	{
		//CalcCohesion();
		Vec3 alignmentAccel;
		Vec3 cohesionAccel;
		Vec3 separationAccel;
		CalcFlockBehavior(bc,alignmentAccel,cohesionAccel,separationAccel);

		//! Adjust for allignment,
		//m_accel += alignmentAccel.Normalized()*ALIGNMENT_FACTOR;
		m_accel += alignmentAccel*bc.factorAlignment;
		m_accel += cohesionAccel*bc.factorCohesion;
		m_accel += separationAccel;
	}

	/*
	// Avoid land.
	if (height < bc.MinHeight && !m_landing)
	{
		float v = (1.0f - height/bc.MinHeight);
		m_accel += Vec3(0,0,v*v)*bc.factorAvoidLand;
	}
	else if (height > bc.MaxHeight) // Avoid max height.
	{
		float v = (height - bc.MaxHeight)*0.1f;
		m_accel += Vec3(0,0,-v);
	}
	else
	{
		// Always try to accelerate in direction oposite to current in Z axis.
		m_accel.z = -(m_heading.z*m_heading.z*m_heading.z * 100.0f);
	}
	*/

	// Attract to origin point.
	if (bc.followPlayer)
	{
		m_accel += (bc.playerPos - m_pos) * bc.factorAttractToOrigin;
	}
	else
	{
		//m_accel += (m_birdOriginPos - m_pos) * bc.factorAttractToOrigin;
		if ((cry_rand()&31) == 1)
		{
			m_birdOriginPos = Vec3(	bc.flockPos.x+frand()*bc.fSpawnRadius,bc.flockPos.y+frand()*bc.fSpawnRadius,bc.flockPos.z+frand()*bc.fSpawnRadius );
			if (m_birdOriginPos.z - bc.terrainZ < bc.MinHeight)
			{
				m_birdOriginPos.z = bc.terrainZ + bc.MinHeight;
			}
		}

		/*
		if (m_pos.x < bc.flockPos.x-bc.fSpawnRadius || m_pos.x > bc.flockPos.x+bc.fSpawnRadius ||
		m_pos.y < bc.flockPos.y-bc.fSpawnRadius || m_pos.y > bc.flockPos.y+bc.fSpawnRadius ||
		m_pos.z < bc.flockPos.z-bc.fSpawnRadius || m_pos.z > bc.flockPos.z+bc.fSpawnRadius)
		*/
		{
			m_accel += (m_birdOriginPos - m_pos) * bc.factorAttractToOrigin;
		}
	}


	// Avoid collision with Terrain and Static objects.
	float fCollisionAvoidanceWeight = 10.0f;

	// Do walk sounds.
	if ((cry_rand()&0xFF) == 0)
		PlaySound(CHICKEN_SOUND_CLUCK);

	//////////////////////////////////////////////////////////////////////////
	// Player must scare chickens off.
	//////////////////////////////////////////////////////////////////////////
	float fScareDist = 5.0f;
	float sqrPlayerDist = m_pos.GetSquaredDistance(bc.playerPos);
	if (sqrPlayerDist < fScareDist*fScareDist)
	{
		Vec3 retreatDir = (m_pos - bc.playerPos) + Vec3(frand()*2.0f,frand()*2.0f,0);
		retreatDir.NormalizeFast();
		float scareFactor = (1.0f - sqrPlayerDist/(fScareDist*fScareDist));
		m_accel.x += retreatDir.x*scareFactor*bc.factorAvoidLand;
		m_accel.y += retreatDir.y*scareFactor*bc.factorAvoidLand;

		m_bScared = true;
		if (m_landing) m_flightTime = m_maxIdleTime+1.0f; // Stop idle.
		// Do walk sounds.
		if ((cry_rand()&0xFF) == 0)
			PlaySound(CHICKEN_SOUND_SCARED);
	}

	//////////////////////////////////////////////////////////////////////////
	// Scare points also scare chicken off.
	//////////////////////////////////////////////////////////////////////////
	if (bc.scareRatio > 0)
	{
		float sqrScareDist = m_pos.GetSquaredDistance(bc.scarePoint);
		if (sqrScareDist < bc.scareRadius*bc.scareRadius)
		{
			float fScareMultiplier = 10.0f;
			Vec3 retreatDir = m_pos - bc.scarePoint;
			retreatDir.NormalizeFast();
			float scareFactor = (1.0f - sqrScareDist/(bc.scareRadius*bc.scareRadius));
			m_accel.x += retreatDir.x*scareFactor*fScareMultiplier;
			m_accel.y += retreatDir.y*scareFactor*fScareMultiplier;

			if (m_landing) m_flightTime = m_maxIdleTime+1.0f; // Stop idle.

			m_bScared = true;

			// Do walk sounds.
			if ((cry_rand()&0xF) == 0)
				PlaySound(CHICKEN_SOUND_CLUCK);
		}
	}
	//////////////////////////////////////////////////////////////////////////


	if (bc.avoidObstacles)
	{
		// Avoid obstacles & terrain.
		IPhysicalWorld *physWorld = bc.physics;

		Vec3 vDir0 = m_heading*bc.fBoidRadius*0.5f;
		Vec3 vPos = m_pos + Vec3(0,0,bc.fBoidRadius*0.5f) + vDir0;
		Vec3 vDir = m_heading*(bc.fBoidRadius*2) + Vec3(0,0,bc.fBoidRadius*0.5f);
		// Add some random variation in probe ray.
		vDir.x += frand()*0.5f;
		vDir.y += frand()*0.5f;

		int objTypes = ent_all|ent_no_ondemand_activation;
		int flags = rwi_stop_at_pierceable|rwi_ignore_terrain_holes;
		ray_hit hit;
		int col = physWorld->RayWorldIntersection( vPos,vDir,objTypes,flags,&hit,1 );
		if (col != 0 && hit.dist > 0)
		{
			// Turn from collided surface.
			Vec3 normal = hit.n;
			float rayLen = vDir.GetLength();
			float w = (1.0f - hit.dist/rayLen);
			Vec3 R = m_heading - (2.0f*m_heading.Dot(normal))*normal;
			R.NormalizeFast();
			R += normal;
			//m_accel += R*(w*w)*bc.factorAvoidLand * fCollisionAvoidanceWeight;
			Vec3 accel = R*w*bc.factorAvoidLand * fCollisionAvoidanceWeight;
			m_avoidanceAccel = m_avoidanceAccel*bc.fSmoothFactor + accel*(1.0f-bc.fSmoothFactor);
		}
	}

	m_accel += m_avoidanceAccel;
	m_avoidanceAccel = m_avoidanceAccel*bc.fSmoothFactor;

	if (!m_landing)
	{
		m_flightTime += dt;
		if (m_flightTime > m_maxNonIdleTime && (m_pos.z > bc.waterLevel && bc.bAvoidWater))
		{
			// Play idle.
			PlayAnimationId( CHICKEN_IDLE_ANIM + (cry_rand()%CHICKEN_IDLE_ANIM_NUM),true );
			m_maxIdleTime = 2.0f + cry_frand()*MAX_REST_TIME;
			m_landing = true;
			m_flightTime = 0;
			
			m_accel.Set(0,0,0);
			m_speed = 0;
		}
	}
	else
	{
		m_accel = m_heading;
		m_speed = 0.1f;

		m_flightTime += dt;
		if (m_flightTime > m_maxIdleTime)
		{
			m_maxNonIdleTime = cry_frand()*MAX_WALK_TIME;
			PlayAnimationId( CHICKEN_WALK_ANIM,true );
			m_landing = false;
			m_flightTime = 0;
		}
	}

	// Limits birds to above water and land.
	m_pos.z = bc.engine->GetTerrainElevation(m_pos.x,m_pos.y) + bc.fBoidRadius*0.5f;
	m_accel.z = 0;

	//////////////////////////////////////////////////////////////////////////
	// Avoid water ocean..
	if (m_pos.z < bc.waterLevel && bc.bAvoidWater)
	{
		if (m_landing)
			m_flightTime = m_maxIdleTime;
		Vec3 nextpos = m_pos + m_heading;
		float farz = bc.engine->GetTerrainElevation(nextpos.x,nextpos.y) + bc.fBoidRadius*0.5f;
		if (farz > m_pos.z)
			m_accel += m_heading*bc.factorAvoidLand;
		else
			m_accel += -m_heading*bc.factorAvoidLand;
		m_accel.z = 0;
	}
	//////////////////////////////////////////////////////////////////////////
}
예제 #6
0
void CBoidBird::ThinkWalk( float dt,SBoidContext &bc )
{

	m_accel = -m_heading*(m_speed-m_walkSpeed)*0.4f;


	if (bc.factorAlignment != 0)
	{
		Vec3 alignmentAccel;
		Vec3 cohesionAccel;
		Vec3 separationAccel;
		CalcFlockBehavior(bc,alignmentAccel,cohesionAccel,separationAccel);

		m_accel += alignmentAccel*bc.factorAlignmentGround;
		m_accel += cohesionAccel*bc.factorCohesionGround;
		m_accel += separationAccel*bc.factorSeparationGround;
	}


	// Attract to origin point.
	if (bc.followPlayer)
	{
		m_accel += (bc.playerPos - m_pos) * bc.factorAttractToOriginGround;
	}
	else
	{
		if ((cry_rand()&31) == 1)
		{
			m_birdOriginPos = Vec3(	bc.flockPos.x+Boid::Frand()*bc.fSpawnRadius,bc.flockPos.y+Boid::Frand()*bc.fSpawnRadius,bc.flockPos.z+Boid::Frand()*bc.fSpawnRadius );
			if (m_birdOriginPos.z - bc.terrainZ < bc.MinHeight)
			{
				m_birdOriginPos.z = bc.terrainZ + bc.MinHeight;
			}
		}

		m_accel += (m_birdOriginPos - m_pos) * bc.factorAttractToOriginGround;
	}


	// Avoid collision with Terrain and Static objects.
	float fCollisionAvoidanceWeight = 10.0f;

	// Do walk sounds.
// 	if ((cry_rand()&0xFF) == 0)
// 		PlaySound(CHICKEN_SOUND_CLUCK);


	
	m_accel.z = 0;

	//////////////////////////////////////////////////////////////////////////
	// Avoid water ocean..
	if (m_pos.z < bc.waterLevel && bc.bAvoidWater)
	{
		Vec3 nextpos = m_pos + m_heading;
		float farz = bc.engine->GetTerrainElevation(nextpos.x,nextpos.y) + bc.fBoidRadius*0.5f;
		if (farz > m_pos.z)
			m_accel += m_heading*bc.factorAvoidLand;
		else
			m_accel += -m_heading*bc.factorAvoidLand;
		m_accel.z = 0;
	}
	//////////////////////////////////////////////////////////////////////////
}
예제 #7
0
void CPlayerStateJump::Landed(CPlayer& player, const bool isHeavyWeapon, float fallSpeed)
{
#ifdef STATE_DEBUG
	bool remoteControlled = false;
	IVehicle* pVehicle = player.GetLinkedVehicle();
	if(pVehicle)
	{
		IVehicleSeat* pVehicleSeat = pVehicle->GetSeatForPassenger(player.GetEntityId());
		if(pVehicleSeat && pVehicleSeat->IsRemoteControlled())
		{
			remoteControlled = true;
		}
	}
	CRY_ASSERT_MESSAGE( player.GetLinkedEntity()==NULL || remoteControlled, "Cannot 'land' when you're linked to another entity!" );
#endif

	const SPlayerStats& stats = player.m_stats;

	Vec3 playerPosition = player.GetEntity()->GetWorldPos();
	IPhysicalEntity *phys = player.GetEntity()->GetPhysics();
	IMaterialEffects *mfx = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects();

	const SActorPhysics& actorPhysics = player.GetActorPhysics();
	int matID = actorPhysics.groundMaterialIdx != -1 ? actorPhysics.groundMaterialIdx : mfx->GetDefaultSurfaceIndex();

	const float fHeightofEntity = playerPosition.z;
	const float worldWaterLevel = player.m_playerStateSwim_WaterTestProxy.GetWaterLevel();
	
	TMFXEffectId effectId = mfx->GetEffectId("bodyfall", matID);
	if (effectId != InvalidEffectId)
	{
		SMFXRunTimeEffectParams params;
		Vec3 direction = Vec3(0,0,0);
		if (IMovementController *pMV = player.GetMovementController())
		{
			SMovementState state;
			pMV->GetMovementState(state);
			direction = state.aimDirection;
		}
		params.pos = playerPosition + direction;
		//params.soundSemantic = eSoundSemantic_Player_Foley;

		float landFallParamVal = (float)__fsel( -(fallSpeed - 7.5f), 0.25f, 0.75f);
		params.AddAudioRtpc("landfall", landFallParamVal);

		const float speedParamVal = min(fabsf((actorPhysics.velocity.z * 0.1f)), 1.0f);
		params.AddAudioRtpc("speed", speedParamVal);

		mfx->ExecuteEffect(effectId, params);
	}

	bool heavyLanded = false;

	IItem* pCurrentItem = player.GetCurrentItem();
	CWeapon* pCurrentWeapon = pCurrentItem ? static_cast<CWeapon*>(pCurrentItem->GetIWeapon()) : NULL;

	if (fallSpeed > 0.0f && player.IsPlayer())
	{
		if(!gEnv->bMultiplayer)
		{
			const float verticalSpeed = fabs(fallSpeed);
			const float speedForHeavyLand = g_pGameCVars->pl_health.fallSpeed_HeavyLand;
			if ((verticalSpeed >= speedForHeavyLand) && (player.GetPickAndThrowEntity() == 0) && !player.IsDead())
			{
				if ( !isHeavyWeapon )
				{
					if (pCurrentWeapon)
					{
						pCurrentWeapon->FumbleGrenade();
						pCurrentWeapon->CancelCharge();
					}

					player.StartInteractiveActionByName("HeavyLand", false);
				}
				heavyLanded = true;
			}
		}
	}

	if(player.m_isClient)
	{
		if (fallSpeed > 0.0f)
		{
			const float fallIntensityMultiplier = stats.wasHit ? g_pGameCVars->pl_fall_intensity_hit_multiplier : g_pGameCVars->pl_fall_intensity_multiplier;
			const float fallIntensityMax = g_pGameCVars->pl_fall_intensity_max;
			const float fallTimeMultiplier = g_pGameCVars->pl_fall_time_multiplier;
			const float fallTimeMax = g_pGameCVars->pl_fall_time_max;
			const float zoomMultiplayer = (pCurrentWeapon && pCurrentWeapon->IsZoomed()) ? 0.2f : 1.0f;
			const float direction = ((cry_rand()%2)==0) ? -1.0f : 1.0f;
			const float intensity = clamp_tpl(fallIntensityMultiplier*fallSpeed*zoomMultiplayer, 0.0f, fallIntensityMax);
			const float shakeTime = clamp_tpl(fallTimeMultiplier*fallSpeed*zoomMultiplayer, 0.0f, fallTimeMax);
			const Vec3 rotation = Vec3(-0.5f, 0.15f*direction, 0.05f*direction);

			if (CScreenEffects* pGameScreenEffects = g_pGame->GetScreenEffects())
			{
				pGameScreenEffects->CamShake(rotation*intensity, Vec3(0, 0, 0), shakeTime, shakeTime, 0.05f, CScreenEffects::eCS_GID_Player);
			}

			IForceFeedbackSystem* pForceFeedback = g_pGame->GetIGameFramework()->GetIForceFeedbackSystem();
			assert(pForceFeedback);

			ForceFeedbackFxId fxId = pForceFeedback->GetEffectIdByName("landFF");
			pForceFeedback->PlayForceFeedbackEffect(fxId, SForceFeedbackRuntimeParams(intensity, 0.0f));

			if(fallSpeed > 7.0f)
			{
				player.PlaySound(CPlayer::ESound_Fall_Drop);
			}

			CPlayer::EPlayerSounds playerSound = heavyLanded ? CPlayer::ESound_Gear_HeavyLand : CPlayer::ESound_Gear_Land;
			player.PlaySound(playerSound, true);
		}
		CCCPOINT(PlayerMovement_LocalPlayerLanded);
	}
	
	if( gEnv->pAISystem )
	{
		// Notify AI
		//If silent feet active, ignore here
		const float noiseSupression = 0.0f;
		const float fAISoundRadius = (g_pGameCVars->ai_perception.landed_baseRadius + (g_pGameCVars->ai_perception.landed_speedMultiplier * fallSpeed)) * (1.0f - noiseSupression);
		SAIStimulus stim(AISTIM_SOUND, AISOUND_MOVEMENT_LOUD, player.GetEntityId(), 0,
			player.GetEntity()->GetWorldPos() + player.GetEyeOffset(), ZERO, fAISoundRadius);
		gEnv->pAISystem->RegisterStimulus(stim);
	}

	// Record 'Land' telemetry stats.

	CStatsRecordingMgr::TryTrackEvent(&player, eGSE_Land, fallSpeed);

	if (fallSpeed > 0.0f)
	{
		player.CreateScriptEvent( heavyLanded ? "heavylanded" : "landed",stats.fallSpeed);
	}
}