//--------------------------------------------------------------------------------------------------
// Name: SpawnMaterialEffect
// Desc: Spawns material effect
//--------------------------------------------------------------------------------------------------
void CExplosionGameEffect::SpawnMaterialEffect(const SExplosionContainer &explosionContainer)
{
	// Disclaimer: this code was originally from GameRulesClientServer::ProcessExplosionMaterialFX()
	const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo;

	// impact stuff here
	SMFXRunTimeEffectParams params;
	//params.soundSemantic = eSoundSemantic_Explosion;
	params.pos = params.decalPos = explosionInfo.pos;
	params.trg = 0;
	params.trgRenderNode = 0;
	params.trgSurfaceId = 0;

	if(explosionInfo.impact && (explosionInfo.impact_velocity.len2() > 0.000001f))
	{
		params.dir[0] = explosionInfo.impact_velocity.normalized();
		params.normal = explosionInfo.impact_normal;
	}
	else
	{
		const Vec3 gravityDir = Vec3(0.0f, 0.0f, -1.0f);

		params.dir[0] = gravityDir;
		params.normal = -gravityDir;
	}

	const SDeferredMfxExplosion& mfxInfo = explosionContainer.m_mfxInfo;
	if(mfxInfo.m_state == eDeferredMfxExplosionState_ResultImpact)
	{
		params.trgSurfaceId = mfxInfo.m_mfxTargetSurfaceId;

		if (mfxInfo.m_pMfxTargetPhysEnt.get())
		{
			if (mfxInfo.m_pMfxTargetPhysEnt->GetiForeignData() == PHYS_FOREIGN_ID_STATIC)
			{
				params.trgRenderNode = (IRenderNode*)mfxInfo.m_pMfxTargetPhysEnt->GetForeignData(PHYS_FOREIGN_ID_STATIC);
			}
		}
	}

	// Create query name
	stack_string effectClass = explosionInfo.effect_class;
	if(effectClass.empty())
		effectClass = "generic";

	const float waterLevel = gEnv->p3DEngine->GetWaterLevel(&params.pos); 

	stack_string query = effectClass + "_explode";
	if(waterLevel > explosionInfo.pos.z)
		query = query + "_underwater";

	// Get material effect id
	IMaterialEffects* pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects();
	TMFXEffectId effectId = pMaterialEffects->GetEffectId(query.c_str(), params.trgSurfaceId);

	if(effectId == InvalidEffectId)
	{
		// Get default surface id
		effectId = pMaterialEffects->GetEffectId(query.c_str(), pMaterialEffects->GetDefaultSurfaceIndex());
	}

	// Execute material effect
	if(effectId != InvalidEffectId)
	{
		pMaterialEffects->ExecuteEffect(effectId, params);

		bool hasFlashBangEffect = explosionInfo.blindAmount > 0.0f;
		if(hasFlashBangEffect)
		{
			// Calc screen pos
			Vec3 screenspace;
			gEnv->pRenderer->ProjectToScreen(explosionInfo.pos.x, explosionInfo.pos.y, explosionInfo.pos.z, &screenspace.x, &screenspace.y, &screenspace.z);

			// Pass screen pos to flow graph node
			SMFXCustomParamValue paramPosX;
			paramPosX.fValue = screenspace.x*0.01f;
			pMaterialEffects->SetCustomParameter(effectId,"Intensity",paramPosX); // Use intensity param to pass x pos

			SMFXCustomParamValue paramPosY;
			paramPosY.fValue = screenspace.y*0.01f;
			pMaterialEffects->SetCustomParameter(effectId,"BlendOutTime",paramPosY); // Use blendOutTime param to pass y pos
		}
	}
}//-------------------------------------------------------------------------------------------------
Beispiel #2
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);
	}
}
Beispiel #3
0
//---------------------------------------------------
void CGameRules::ProcessExplosionMaterialFX(const ExplosionInfo &explosionInfo)
{
	// if an effect was specified, don't use MFX
	if (explosionInfo.pParticleEffect)
		return;

	// impact stuff here
	SMFXRunTimeEffectParams params;
	params.soundSemantic = eSoundSemantic_Explosion;
	params.pos = params.decalPos = explosionInfo.pos;
	params.trg = 0;
	params.trgRenderNode = 0;

	Vec3 gravity;
	pe_params_buoyancy buoyancy;
	gEnv->pPhysicalWorld->CheckAreas(params.pos, gravity, &buoyancy);

	// 0 for water, 1 for air
	Vec3 pos=params.pos;
	params.inWater = (buoyancy.waterPlane.origin.z > params.pos.z) && (gEnv->p3DEngine->GetWaterLevel(&pos)>=params.pos.z);
	params.inZeroG = (gravity.len2() < 0.0001f);
	params.trgSurfaceId = 0;

	static const int objTypes = ent_all;    
	static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;

	ray_hit ray;

	if (explosionInfo.impact)
	{
		params.dir[0] = explosionInfo.impact_velocity.normalized();
		params.normal = explosionInfo.impact_normal;

		if (gEnv->pPhysicalWorld->RayWorldIntersection(params.pos-params.dir[0]*0.0125f, params.dir[0]*0.25f, objTypes, flags, &ray, 1))
		{
			params.trgSurfaceId = ray.surface_idx;
			if (ray.pCollider->GetiForeignData()==PHYS_FOREIGN_ID_STATIC)
				params.trgRenderNode = (IRenderNode*)ray.pCollider->GetForeignData(PHYS_FOREIGN_ID_STATIC);
		}
	}
	else
	{
		params.dir[0] = gravity;
		params.normal = -gravity.normalized();

		if (gEnv->pPhysicalWorld->RayWorldIntersection(params.pos, gravity, objTypes, flags, &ray, 1))
		{
			params.trgSurfaceId = ray.surface_idx;
			if (ray.pCollider->GetiForeignData()==PHYS_FOREIGN_ID_STATIC)
				params.trgRenderNode = (IRenderNode*)ray.pCollider->GetForeignData(PHYS_FOREIGN_ID_STATIC);
		}
	}

	string effectClass = explosionInfo.effect_class;
	if (effectClass.empty())
		effectClass = "generic";

	string query = effectClass + "_explode";
	if(gEnv->p3DEngine->GetWaterLevel(&explosionInfo.pos)>explosionInfo.pos.z)
		query = query + "_underwater";

	IMaterialEffects* pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects();
	TMFXEffectId effectId = pMaterialEffects->GetEffectId(query.c_str(), params.trgSurfaceId);

	if (effectId == InvalidEffectId)
		effectId = pMaterialEffects->GetEffectId(query.c_str(), pMaterialEffects->GetDefaultSurfaceIndex());

	if (effectId != InvalidEffectId)
		pMaterialEffects->ExecuteEffect(effectId, params);
}
Beispiel #4
0
//------------------------------------------------------------------------
void CTornado::Update(SEntityUpdateContext &ctx, int updateSlot)
{
	if (g_pGame->GetIGameFramework()->IsEditing())
		return;

	// wandering
	Matrix34 m = GetEntity()->GetWorldTM();
	Vec3 dir(m.GetColumn(1));
	Vec3 pos(GetEntity()->GetWorldPos());

	if(!gEnv->bServer)
		pos = m_currentPos;

	Vec3 wanderPos(dir * 1.414214f);
	float wanderStrength(1.0f);
	float wanderRate(0.6f);
	Vec3 wanderOffset;
	wanderOffset.SetRandomDirection();
	wanderOffset.z = 0.0f;
	wanderOffset.NormalizeSafe(Vec3(1,0,0));
	m_wanderDir += wanderOffset * wanderRate + (m_wanderDir - wanderPos) * wanderStrength;
	m_wanderDir = (m_wanderDir - wanderPos).GetNormalized() + wanderPos;

	Vec3 wanderSteer = (dir + m_wanderDir * gEnv->pTimer->GetFrameTime());
	wanderSteer.z = 0;
	wanderSteer.NormalizeSafe(Vec3(1,0,0));

	Vec3 targetSteer(0,0,0);
	// go to target
	if (m_pTargetEntity)
	{
		Vec3 target = m_pTargetEntity->GetWorldPos() - pos;
		if (target.GetLength() < 10.0f)
		{
			// emit target reached event
			SEntityEvent event( ENTITY_EVENT_SCRIPT_EVENT );
			event.nParam[0] = (INT_PTR)"TargetReached";
			event.nParam[1] = IEntityClass::EVT_BOOL;
			bool bValue = true;
			event.nParam[2] = (INT_PTR)&bValue;
			GetEntity()->SendEvent( event );
			if (m_pTargetCallback)
				m_pTargetCallback->Done();

			m_pTargetEntity = 0;
			m_pTargetCallback = 0;
		}

		targetSteer = (target - dir);
		targetSteer.z = 0;
		targetSteer.NormalizeSafe(Vec3(1,0,0));
	}

	Vec3 steerDir = (0.4f * wanderSteer + 0.6f * targetSteer).GetNormalized();
	Matrix34 tm = Matrix34(Matrix33::CreateRotationVDir(steerDir));
	pos = pos + steerDir * gEnv->pTimer->GetFrameTime() * m_wanderSpeed;
	pos.z = gEnv->p3DEngine->GetTerrainElevation(pos.x, pos.y);
	float waterLevel = gEnv->p3DEngine->GetWaterLevel(&pos);

	bool prevIsOnWater = m_isOnWater;
	m_isOnWater = (pos.z < waterLevel);
	if (m_isOnWater)
	{
		pos.z = waterLevel;
	}

	// raycast does not work for oceans
	if (prevIsOnWater != m_isOnWater && m_isOnWater)
	{
			m_pGroundEffect->SetParticleEffect("weather.tornado.water");
	}
	else if (!m_isOnWater)
	{		
		IMaterialEffects *mfx = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects();
		Vec3 down = Vec3(0,0,-1.0f);
		int matID = mfx->GetDefaultSurfaceIndex();

		static const int objTypes = ent_all;    
		static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
		ray_hit hit;
		int col = gEnv->pPhysicalWorld->RayWorldIntersection(pos, (down * 5.0f), objTypes, flags, &hit, 1, GetEntity()->GetPhysics());
		if (col)
		{
			matID = hit.surface_idx;
		}

		if (m_curMatID != matID)
		{
			TMFXEffectId effectId = mfx->GetEffectId("tornado", matID);
			
			SMFXResourceListPtr pList = mfx->GetResources(effectId);
			if (pList && pList->m_particleList)
			{
				m_pGroundEffect->SetParticleEffect(pList->m_particleList->m_particleParams.name);
			}
			m_curMatID = matID;
		}
	}

	if(gEnv->bServer)
	{
		tm.SetTranslation(pos);
		m_currentPos = pos;
		CHANGED_NETWORK_STATE(this, POSITION_ASPECT);
		GetEntity()->SetWorldTM(tm);
	}
	else
	{
		tm.SetTranslation(m_currentPos);
		GetEntity()->SetWorldTM(tm);
	}

	UpdateParticleEmitters();
	UpdateTornadoSpline();

	UpdateFlow();
}