Ejemplo n.º 1
0
//------------------------------------------------------------------------
void CVehicleMountedWeapon::CorrectRipperEntityPosition(float timeStep)
{
	IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId);
	if(pVehicle)
	{
		const IEntity* pVehicleEnt = pVehicle->GetEntity();

		Vec3 posDiff(ZERO);
		IActor* pOwner = GetOwnerActor();
		if (pOwner && pOwner->IsPlayer())
		{
			CPlayer* pPlayer	 = static_cast<CPlayer*>(pOwner); 
			const Matrix34& wMat = pVehicleEnt->GetWorldTM(); 
			Vec3 vehiclePos		 = wMat.GetTranslation();
			Vec3 currWSpaceRipUserOffset = wMat.TransformPoint(m_localRipUserOffset);

			posDiff = currWSpaceRipUserOffset - m_previousWSpaceOffsetPosition;

			// Don't want to overwrite anyone else changes with an absolute 'set'
			pOwner->GetEntity()->SetPos(pOwner->GetEntity()->GetWorldPos() + posDiff); 

			m_previousWSpaceOffsetPosition = currWSpaceRipUserOffset;

			//Update view limit direction based on change in vehicle rotation
			if(pPlayer->IsClient())
			{
				SViewLimitParams &viewLimits = pPlayer->GetActorParams().viewLimits;
				if(viewLimits.GetViewLimitRangeH()) //Don't do this unless we are currently horizontally constrained
				{
					Quat vehicleRotation(wMat);
					Quat rotationChange = vehicleRotation * m_previousVehicleRotation.GetInverted();

					Vec3 viewLimitDir = rotationChange * viewLimits.GetViewLimitDir();
					viewLimitDir.z = 0.f;
					viewLimitDir.Normalize();

					viewLimits.SetViewLimit(viewLimitDir, 0.01f, 0.01f, 0.f, 0.f, SViewLimitParams::eVLS_Item);

					m_previousVehicleRotation = vehicleRotation;
				}

				//Reset the pitch/roll view angles over time
				Quat viewDirFinal = pPlayer->GetViewQuatFinal();
				Ang3 viewAngles(viewDirFinal);
				float xAdjustment = (float)__fsel(viewAngles.x, max(-viewAngles.x, -0.5f * timeStep), min(-viewAngles.x, 0.5f * timeStep));
				float yAdjustment = (float)__fsel(viewAngles.y, max(-viewAngles.y, -0.5f * timeStep), min(-viewAngles.y, 0.5f * timeStep));

				if(xAdjustment || yAdjustment)
				{
					pPlayer->AddViewAngles(Ang3(xAdjustment, yAdjustment, 0.f));
				}
			}
		}
	}
}
//------------------------------------------------------------------------
void CVehicleActionDeployRope::Update(const float deltaTime)
{
	if (!m_ropeUpperId && !m_ropeLowerId && !m_actorId)
		return;

	IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
	assert(pActorSystem);

	IActor* pActor = pActorSystem->GetActor(m_actorId);
	if (!pActor)
		return;

	Vec3 worldPos = pActor->GetEntity()->GetWorldTM().GetTranslation();

	if (IRopeRenderNode* pRopeUpper = GetRopeRenderNode(m_ropeUpperId))
	{
		Vec3 points[2];
		points[0] = m_pRopeHelper->GetWorldTM().GetTranslation();
		points[1] = worldPos;

		pRopeUpper->SetPoints(points, 2);

		float lenghtLeft = max(0.0f, g_ropeLenght - (points[0].z - points[1].z));

		if (IRopeRenderNode* pRopeLower = GetRopeRenderNode(m_ropeLowerId))
		{
			Vec3 points[2];
			points[0] = worldPos;
			points[1] = Vec3(worldPos.x, worldPos.y, worldPos.z - lenghtLeft);

			pRopeLower->SetPoints(points, 2);
		}
	}
}
//------------------------------------------------------------------------
void CVehicleActionDeployRope::OnVehicleEvent(EVehicleEvent event, const SVehicleEventParams& params)
{
	if (event == eVE_PassengerExit && params.iParam == m_seatId)
	{
		IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
		assert(pActorSystem);

		IActor* pActor = pActorSystem->GetActor(params.entityId);
		if (!pActor)
		{
			assert(pActor);
			return;
		}

		m_actorId = pActor->GetEntityId();

		DeployRope();
		AttachOnRope(pActor->GetEntity());
	} 
	else if (event == eVE_Destroyed)
	{
		if (m_ropeUpperId)
		{
			gEnv->pEntitySystem->RemoveEntity(m_ropeUpperId);
			m_ropeUpperId = 0;
		}

		if (m_ropeLowerId)
		{
			gEnv->pEntitySystem->RemoveEntity(m_ropeLowerId);
			m_ropeLowerId = 0;
		}
	}
}
Ejemplo n.º 4
0
void CMFXForceFeedbackEffect::Execute(SMFXRunTimeEffectParams& params)
{
	FUNCTION_PROFILER(gEnv->pSystem, PROFILE_ACTION);

	if (params.playflags & MFX_PLAY_FORCEFEEDBACK)
	{
		float distanceToPlayerSqr = FLT_MAX;
		IActor *pClientActor = gEnv->pGame->GetIGameFramework()->GetClientActor();
		if (pClientActor)
		{
			distanceToPlayerSqr = (pClientActor->GetEntity()->GetWorldPos() - params.pos).GetLengthSquared();
		}

		const float testDistanceSqr = clamp_tpl(distanceToPlayerSqr, m_forceFeedbackParams.intensityFallOffMinDistanceSqr, m_forceFeedbackParams.intensityFallOffMaxDistanceSqr);
		const float minMaxDiffSqr = m_forceFeedbackParams.intensityFallOffMaxDistanceSqr - m_forceFeedbackParams.intensityFallOffMinDistanceSqr;
		
		float effectIntensity = (float)__fsel(-minMaxDiffSqr, 0.0f, 1.0f - (testDistanceSqr - m_forceFeedbackParams.intensityFallOffMinDistanceSqr) / (minMaxDiffSqr + FLT_EPSILON));
		effectIntensity *= effectIntensity;
		if (effectIntensity > 0.01f)
		{
			IForceFeedbackSystem* pForceFeedback = CCryAction::GetCryAction()->GetIForceFeedbackSystem();
			assert(pForceFeedback);
			ForceFeedbackFxId fxId = pForceFeedback->GetEffectIdByName(m_forceFeedbackParams.forceFeedbackEventName.c_str());
			pForceFeedback->PlayForceFeedbackEffect(fxId, SForceFeedbackRuntimeParams(effectIntensity, 0.0f));
		}
	}

}
void CDevMode::GotoTagPoint( int i )
{
	std::vector<STagFileEntry> tags = LoadTagFile();
	if (tags.size() > size_t(i))
	{
		STagFileEntry ent = tags[i];
		IActor * pActor = CCryAction::GetCryAction()->GetClientActor();
		if (!pActor) return;
		IEntity * pEntity = pActor->GetEntity();
		Quat rot;

		Vec3 pos = ent.pos;

		// pos loaded is a camera position, we must convert it into the player position.
		if (IMovementController * pMC = pActor->GetMovementController())
		{
			SMovementState ms;
			pMC->GetMovementState(ms);
			pos -= (ms.eyePosition-ms.pos);
		}

		rot.SetRotationXYZ( ent.ang );
		Vec3 scale = pEntity->GetScale();
		pEntity->SetPosRotScale( pos, rot, scale );
		pActor->SetViewRotation( rot );
	}
}
Ejemplo n.º 6
0
bool CGameRulesSpawningBase::CanPlayerSpawnThisRound(const EntityId playerId) const
{
	bool allowed=true;

	IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(playerId);

	if (pActor->IsPlayer())
	{
		CGameRules *pGameRules = g_pGame->GetGameRules();
		IGameRulesPlayerStatsModule *playerStats = pGameRules ? pGameRules->GetPlayerStatsModule() : NULL;

		if (playerStats)
		{
			const SGameRulesPlayerStat *stats = playerStats->GetPlayerStats(playerId);
			if (stats)
			{
				if (stats->flags & SGameRulesPlayerStat::PLYSTATFL_CANTSPAWNTHISROUND)
				{	
					allowed=false;
				}
			}
		}
	}

	CryLog("CGameRulesSpawningBase::CanPlayerSpawnThisRound() player=%s allowed=%d", pActor->GetEntity()->GetName(), allowed);
	return allowed;
}
Ejemplo n.º 7
0
//------------------------------------------------------------------------
void CProjectile::Update(SEntityUpdateContext &ctx, int updateSlot)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	if (updateSlot!=0)
		return;

	float color[4] = {1,1,1,1};
	bool bDebug = g_pGameCVars->i_debug_projectiles > 0;

	if(bDebug)
		gEnv->pRenderer->Draw2dLabel(50,15,2.0f,color,false,"Projectile: %s",GetEntity()->GetClass()->GetName());

	Vec3 pos = GetEntity()->GetWorldPos();

	ScaledEffect(m_pAmmoParams->pScaledEffect);

	// update whiz
	if(m_pAmmoParams->pWhiz)
	{
		if (m_whizSoundId == INVALID_SOUNDID)
		{
			IActor *pActor = g_pGame->GetIGameFramework()->GetClientActor();
			if (pActor && (m_ownerId != pActor->GetEntityId()))
			{
				float probability = 0.85f;

				if (Random()<=probability)
				{
					Lineseg line(m_last, pos);
					Vec3 player = pActor->GetEntity()->GetWorldPos();

					float t;
					float distanceSq=Distance::Point_LinesegSq(player, line, t);

					if (distanceSq < 4.7f*4.7f && (t>=0.0f && t<=1.0f))
					{
						if (distanceSq >= 0.65*0.65)
						{
							Sphere s;
							s.center = player;
							s.radius = 4.7f;

							Vec3 entry,exit;
							int intersect=Intersect::Lineseg_Sphere(line, s, entry,exit);
							if (intersect==0x1 || intersect==0x3) // one entry or one entry and one exit
								WhizSound(true, entry, (pos-m_last).GetNormalized());
						}
					}
				}
			}
		}
	}

	if (m_trailSoundId==INVALID_SOUNDID)
		TrailSound(true);

	m_totalLifetime += ctx.fFrameTime;
	m_last = pos;
}
void CMFXParticleEffect::Execute(const SMFXRunTimeEffectParams& params)
{
  FUNCTION_PROFILER(gEnv->pSystem, PROFILE_ACTION);

  Vec3 pos = params.pos;
	Vec3 dir = ZERO;
	Vec3 inDir = params.dir[0];
	Vec3 reverso = inDir * -1.0f;
	switch (m_particleParams.directionType)
	{
	case SMFXParticleParams::eDT_Normal:
		dir = params.normal;
		break;
	case SMFXParticleParams::eDT_Ricochet:
		dir = reverso.GetRotated(params.normal, gf_PI).normalize();
		break;
	default:
		dir = params.normal;
		break;
	}
 
  bool tryToAttachEffect = (CMaterialEffectsCVars::Get().mfx_EnableAttachedEffects != 0);
  float distToPlayer = 0.f;
  IActor *pClientActor = gEnv->pGame->GetIGameFramework()->GetClientActor();
  if (pClientActor)
  {
    distToPlayer = (pClientActor->GetEntity()->GetWorldPos() - params.pos).GetLength();
	tryToAttachEffect = tryToAttachEffect && (pClientActor->GetEntityId() != params.trg);
  }
  
  SMFXParticleEntries::const_iterator end = m_particleParams.m_entries.end();
  for (SMFXParticleEntries::const_iterator it = m_particleParams.m_entries.begin(); it!=end; ++it)
  {
    // choose effect based on distance
    if ((it->maxdist == 0.f) || (distToPlayer <= it->maxdist) && !it->name.empty() )
    { 
      IParticleEffect *pParticle = gEnv->pParticleManager->FindEffect(it->name.c_str());

      if (pParticle)
      {
        const float pfx_minscale = (it->minscale != 0.f) ? it->minscale : CMaterialEffectsCVars::Get().mfx_pfx_minScale;
        const float pfx_maxscale = (it->maxscale != 0.f) ? it->maxscale : CMaterialEffectsCVars::Get().mfx_pfx_maxScale; 
        const float pfx_maxdist = (it->maxscaledist != 0.f) ? it->maxscaledist : CMaterialEffectsCVars::Get().mfx_pfx_maxDist; 
                
        const float truscale = pfx_minscale + ((pfx_maxscale - pfx_minscale) * (distToPlayer!=0.f ? min(1.0f, distToPlayer/pfx_maxdist) : 1.f));  

		bool particleSpawnedAndAttached = tryToAttachEffect ? AttachToTarget(*it, params, pParticle, dir, truscale) : false;

        // If not attached, just spawn the particle
		if (particleSpawnedAndAttached == false)
		{
			pParticle->Spawn( true, IParticleEffect::ParticleLoc(pos, dir, truscale) );
		}
      }
      
      break;
    }
  }
}
Ejemplo n.º 9
0
EntityId Mouse::getEntityUnderCursor()
{
	IRenderer* pRenderer = gEnv->pRenderer;

	if(!gEnv->pHardwareMouse || !pRenderer || !gEnv->p3DEngine || !gEnv->pSystem || !gEnv->pEntitySystem || !g_pGame->GetIGameFramework())
		return false;

	IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();

	if (!pClientActor)
		return false;

	float mx, my, cx, cy, cz = 0.0f;

	mx = m_x;
	my = pRenderer->GetHeight() - m_y;

	pRenderer->UnProjectFromScreen(mx, my, 0.0f, &cx, &cy, &cz);

	IPhysicalEntity *pPhysicalEnt = pClientActor->GetEntity() ? pClientActor->GetEntity()->GetPhysics() : NULL;

	if(!pPhysicalEnt)
		return false;

	entity_query_flags queryFlags = ent_all; // see physicsnterface.h for details	
	static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
	float  fRange = gEnv->p3DEngine->GetMaxViewDistance();

	Vec3 vCamPos = gEnv->pSystem->GetViewCamera().GetPosition();
	Vec3 vDir = (Vec3(cx, cy, cz) - vCamPos).GetNormalizedSafe();

	static ray_hit hit;

	if (gEnv->pPhysicalWorld && gEnv->pPhysicalWorld->RayWorldIntersection(vCamPos, vDir * fRange, queryFlags, flags, &hit, 1, pPhysicalEnt))
	{
		CryLogAlways("Entity position: %f, %f, %f", hit.pt.x, hit.pt.y, hit.pt.z);
		if (IEntity* pEntity = gEnv->pEntitySystem->GetEntityFromPhysics(hit.pCollider))
		{						
			CryLogAlways("Entity name:", pEntity->GetName());
			return pEntity->GetId();
		}		
	}

	return 0;
}
Ejemplo n.º 10
0
bool Mouse::getWorldCoords( float& x, float& y, float& z )
{
	IRenderer* pRenderer = gEnv->pRenderer;

	if(!gEnv->pHardwareMouse || !pRenderer || !gEnv->p3DEngine || !gEnv->pSystem || !gEnv->pEntitySystem || !g_pGame->GetIGameFramework())
		return false;

	IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();

	if (!pClientActor)
		return false;

	float mx, my, cx, cy, cz = 0.0f;

	mx = m_x - 4;
	my = pRenderer->GetHeight() - m_y + 10;

	pRenderer->UnProjectFromScreen(mx, my, 0.0f, &cx, &cy, &cz);
	
	IPhysicalEntity *pPhysicalEnt = pClientActor->GetEntity() ? pClientActor->GetEntity()->GetPhysics() : NULL;

	if(!pPhysicalEnt)
		return false;

	entity_query_flags queryFlags = ent_terrain; // see physicsnterface.h for details	
	static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
	float  fRange = gEnv->p3DEngine->GetMaxViewDistance();

	Vec3 vCamPos = gEnv->pSystem->GetViewCamera().GetPosition();
	Vec3 vDir = (Vec3(cx, cy, cz) - vCamPos).GetNormalizedSafe();

	static ray_hit hit;

	if (gEnv->pPhysicalWorld && gEnv->pPhysicalWorld->RayWorldIntersection(vCamPos, vDir * fRange, queryFlags, flags, &hit, 1, pPhysicalEnt))
	{
		x = hit.pt.x;
		y = hit.pt.y;
		z = hit.pt.z;

		return true;
	}

	return false;
}
Ejemplo n.º 11
0
void CTornado::OutputDistance()
{
	IActor *pClient = g_pGame->GetIGameFramework()->GetClientActor();
	if (!pClient)
		return;

	Vec3 deltaToClient(pClient->GetEntity()->GetWorldPos() - GetEntity()->GetWorldPos());
	deltaToClient.z = 0;
	EntityScripts::CallScriptFunction(GetEntity(), GetEntity()->GetScriptTable(), "ScriptEvent", "outputDistance", deltaToClient.len(), 0);
}
Ejemplo n.º 12
0
//------------------------------------------------------------------------
IEntity * CEditorGame::GetPlayer()
{
	IGameFramework * pGameFramework = m_pGame->GetIGameFramework();	

	if(!m_pGame)
		return 0;

	IActor * pActor = pGameFramework->GetClientActor();
	return pActor? pActor->GetEntity() : NULL;
}
//------------------------------------------------------------------------
IMPLEMENT_RMI(CGameRules, SvHostMigrationRequestSetup)
{
	uint16 channelId = m_pGameFramework->GetGameChannelId(pNetChannel);
	IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActorByChannelId(channelId);
	CRY_ASSERT(pActor);
	CryLog("SvHostMigrationRequestSetup, unpacking setup for player '%s', channel=%i", pActor->GetEntity()->GetName(), channelId);
	// 	if (pActor->IsDead() && (params.m_timeToAutoRevive > 0.f))
	// 	{
	// 		IGameRulesSpawningModule *pSpawningModule = GetSpawningModule();
	// 		pSpawningModule->HostMigrationInsertIntoReviveQueue(pActor->GetEntityId(), params.m_timeToAutoRevive * 1000.f);
	// 	}
	return true;
}
Ejemplo n.º 14
0
//------------------------------------------------------------------------
void CEditorGame::SetPlayerPosAng(Vec3 pos,Vec3 viewDir)
{
	IActor * pClActor = m_pGame->GetIGameFramework()->GetClientActor();

	if (pClActor /*&& m_bGameMode*/)
	{
		// pos coming from editor is a camera position, we must convert it into the player position by subtructing eye height.
		IEntity *myPlayer = pClActor->GetEntity();
		if (myPlayer)
		{
			pe_player_dimensions dim;
			dim.heightEye = 0;
			if (myPlayer->GetPhysics())
			{
				myPlayer->GetPhysics()->GetParams( &dim );
				pos.z = pos.z - dim.heightEye;
			}
		}

		pClActor->GetEntity()->SetPosRotScale( pos,Quat::CreateRotationVDir(viewDir),Vec3(1,1,1),ENTITY_XFORM_EDITOR|ENTITY_XFORM_POS|ENTITY_XFORM_ROT|ENTITY_XFORM_SCL);
	}
}
  virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
  {
    switch (event)
    {    
    case eFE_Activate:
      {
        IActor* pActor = GetAIActor(pActInfo);
        if (!pActor)
          break;
        
        IEntity* pEnt = pActor->GetEntity();
        if (!pEnt)
          break;
        
        HSCRIPTFUNCTION func = 0;
        int ret = 0;
        IScriptTable* pTable = pEnt->GetScriptTable();
        if (!pTable)
          break;

        if (IsPortActive(pActInfo, 1) && pTable->GetValue("GrabObject", func))
        {                   
          IEntity* pObj = gEnv->pEntitySystem->GetEntity( GetPortEntityId(pActInfo, 0) );
          if (pObj)
          {
            IScriptTable* pObjTable = pObj->GetScriptTable();
            Script::CallReturn(gEnv->pScriptSystem, func, pTable, pObjTable, ret);
          }
          ActivateOutput(pActInfo, 0, ret);
        }  
        else if (IsPortActive(pActInfo, 2) && pTable->GetValue("DropObject", func))
        {
          bool bThrow = GetPortBool(pActInfo, 3);
          Script::CallReturn(gEnv->pScriptSystem, func, pTable, bThrow, ret);
          ActivateOutput(pActInfo, 0, ret);
        }
        
        if (pTable->GetValue("GetGrabbedObject", func))
        {          
          ScriptHandle sH(0);
          Script::CallReturn(gEnv->pScriptSystem, func, pTable, sH);
          ActivateOutput(pActInfo, 1, EntityId(sH.n));
        }
        
				if(func)
					gEnv->pScriptSystem->ReleaseFunc(func);

        break;
      }
    }
  }
Ejemplo n.º 16
0
void CFlowConvoyNode::SetPlayerMaxVelGround(float vel)
{
	IActor *pPlayerActor = gEnv->pGame->GetIGameFramework()->GetClientActor();
	if(pPlayerActor)
	{
		IPhysicalEntity *pPhysicalEntity=pPlayerActor->GetEntity()->GetPhysics();
		if(pPhysicalEntity)
		{
			pe_player_dynamics ppd;
			ppd.maxVelGround=vel;
			pPhysicalEntity->SetParams(&ppd);
		}
	}
}
Ejemplo n.º 17
0
int CFlowConvoyNode::GetCoachIndexPlayerIsOn2()
{
	IActor *pPlayerActor = gEnv->pGame->GetIGameFramework()->GetClientActor();
	Vec3 playerPos=pPlayerActor->GetEntity()->GetWorldPos();
	for (size_t i = 0; i < m_coaches.size(); ++i)
	{
		AABB bbox;
		m_coaches[i].m_pEntity->GetLocalBounds(bbox);
		Vec3 localpos=m_coaches[i].m_pEntity->GetWorldTM().GetInverted().TransformPoint(playerPos);
		if(bbox.min.x<=localpos.x && bbox.min.y<=localpos.y && bbox.max.x>=localpos.x && bbox.max.y>=localpos.y)
			return i;
	}
	return -1;
}
Ejemplo n.º 18
0
//------------------------------------------------------------------------
bool CEditorGame::SetGameMode(bool bGameMode)
{
	m_bGameMode = bGameMode;
	bool on = bGameMode;
	if (s_pEditorGameMode->GetIVal() == 0)
		on = m_bPlayer;
	bool ok = ConfigureNetContext( on );
	if (ok)
	{
		if(gEnv->IsEditor())
		{
			m_pGame->EditorResetGame(bGameMode);
		}

		IGameFramework * pGameFramework = m_pGame->GetIGameFramework();

		pGameFramework->OnEditorSetGameMode(bGameMode);

		IActor *pActor = m_pGame->GetIGameFramework()->GetClientActor();
		if (pActor)
		{
			if (bGameMode)
			{
				// Revive actor in its current location (it will be moved to the editor viewpoint location later)
				const Vec3 pos = pActor->GetEntity()->GetWorldPos();
				const Quat rot = pActor->GetEntity()->GetWorldRotation();
				const int teamId = g_pGame->GetGameRules()->GetTeam(pActor->GetEntityId());
				g_pGame->GetGameRules()->RevivePlayer(pActor, pos, rot, teamId);
			}
		}
	}
	else
	{
		GameWarning("Failed configuring net context");
	}
	return ok;
}
Ejemplo n.º 19
0
float CFlowConvoyNode::GetPlayerMaxVelGround()
{
	IActor *pPlayerActor = gEnv->pGame->GetIGameFramework()->GetClientActor();
	if(pPlayerActor)
	{
		IPhysicalEntity *pPhysicalEntity=pPlayerActor->GetEntity()->GetPhysics();
		if(pPhysicalEntity)
		{
			pe_player_dynamics ppd;
			pPhysicalEntity->GetParams(&ppd);
			return ppd.maxVelGround;
		}
	}
	return 0;
}
//------------------------------------------------------------------------
void CShake::Update(SEntityUpdateContext &ctx, int updateSlot)
{
	IActor *pClient = g_pGame->GetIGameFramework()->GetClientActor();
	if (pClient)
	{
		float dist2ToClient((pClient->GetEntity()->GetWorldPos() - GetEntity()->GetWorldPos()).len2());
		float maxRange(m_radius * m_radius);
		if (dist2ToClient<maxRange)
		{
			IView *pView = g_pGame->GetIGameFramework()->GetIViewSystem()->GetViewByEntityId(pClient->GetEntityId());
			if (pView)
			{
				float strength = (1.0f - (dist2ToClient/maxRange)) * 0.5f;
				pView->SetViewShake(ZERO,Vec3(m_shake*strength,0,m_shake*strength),0.1f,0.0225f,1.5f,1);
			}
		}
	}
}
Ejemplo n.º 21
0
//------------------------------------------------------------------------
// Example on how to use this function:
//
// local params =
// {
//   name     = "dude",
//   class    = "CSpectator",
//   position = {x=0, y=0, z=0},
//   rotation = {x=0, y=0, z=0},
//   scale    = {x=1, y=1, z=1}
// }
//
// Actor.CreateActor( channelId, params );
//
int CScriptBind_ActorSystem::CreateActor( IFunctionHandler *pH, int channelId, SmartScriptTable actorParams )
{
	CRY_ASSERT( m_pGameFW->GetIActorSystem() != NULL );
	const char *name;
	const char *className;
	Vec3 position;
	Vec3 scale;
	Vec3 rotation;

#define GET_VALUE_FROM_CHAIN( valName, val, chain ) \
	if ( !chain.GetValue( valName, val ) ) \
	{ \
		CryWarning( VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "CreateActor failed because <%s> field not specified", valName ); \
		bFailed = true; \
	}

	// The following code had to be enclosed in a bracket because 
	// CScriptSetGetChain needs to be declared statically and also needs to 
	// be destructed before EndFunction
	bool bFailed = false;
	do
	{
		CScriptSetGetChain actorChain( actorParams );
		GET_VALUE_FROM_CHAIN( "name",     name,      actorChain );
		GET_VALUE_FROM_CHAIN( "class",    className, actorChain );
		GET_VALUE_FROM_CHAIN( "position", position,  actorChain );
		GET_VALUE_FROM_CHAIN( "rotation", rotation,  actorChain );
		GET_VALUE_FROM_CHAIN( "scale",    scale,     actorChain );
	}

	while ( false );

	if ( bFailed )
		return pH->EndFunction(false);

	Quat q;
	q.SetRotationXYZ( Ang3(rotation) );
	IActor* pActor = m_pGameFW->GetIActorSystem()->CreateActor( channelId, name, className, position, q, scale );

	if (pActor == NULL)
		return pH->EndFunction();
	else
		return pH->EndFunction(pActor->GetEntity()->GetScriptTable());
}
Ejemplo n.º 22
0
//------------------------------------------------------------------------
void CGameRules::ClientHit(const HitInfo &hitInfo)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();
	IEntity *pTarget = m_pEntitySystem->GetEntity(hitInfo.targetId);
	IEntity *pShooter =	m_pEntitySystem->GetEntity(hitInfo.shooterId);
	IVehicle *pVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(hitInfo.targetId);
	IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.targetId);
	bool dead = pActor?(pActor->GetHealth()<=0):false;

	if((pClientActor && pClientActor->GetEntity()==pShooter) && pTarget && (pVehicle || pActor) && !dead)
	{
		SAFE_HUD_FUNC(GetCrosshair()->CrosshairHit());
		SAFE_HUD_FUNC(GetTagNames()->AddEnemyTagName(pActor?pActor->GetEntityId():pVehicle->GetEntityId()));
	}

	if(pActor == pClientActor)
		if (gEnv->pInput) gEnv->pInput->ForceFeedbackEvent( SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.5f * hitInfo.damage * 0.01f, hitInfo.damage * 0.02f, 0.0f));

/*	if (gEnv->pAISystem && !gEnv->bMultiplayer)
	{
		static int htMelee = GetHitTypeId("melee");
		if (pShooter && hitInfo.type != htMelee)
		{
			ISurfaceType *pSurfaceType = GetHitMaterial(hitInfo.material);
			const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0;
			const float radius = pParams ? pParams->fImpactRadius : 5.0f;
			gEnv->pAISystem->BulletHitEvent(hitInfo.pos, radius, pShooter->GetAI());
		}
	}*/

	CreateScriptHitInfo(m_scriptHitInfo, hitInfo);
	CallScript(m_clientStateScript, "OnHit", m_scriptHitInfo);

	bool backface = hitInfo.dir.Dot(hitInfo.normal)>0;
	if (!hitInfo.remote && hitInfo.targetId && !backface)
	{
		if (!gEnv->bServer)
			GetGameObject()->InvokeRMI(SvRequestHit(), hitInfo, eRMI_ToServer);
		else
			ServerHit(hitInfo);
	}
}
//------------------------------------------------------------------------
bool CVehicleActionDeployRope::DeployRope()
{
	IActorSystem* pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
	assert(pActorSystem);

	IActor* pActor = pActorSystem->GetActor(m_actorId);
	if (!pActor)
		return false;

	Vec3 upperPos = m_pRopeHelper->GetWorldTM().GetTranslation();
	Vec3 lowerPos(upperPos.x, upperPos.y, upperPos.z - g_ropeLenght);

	m_ropeUpperId = CreateRope(m_pVehicle->GetEntity()->GetPhysics(), upperPos, upperPos);
	m_ropeLowerId = CreateRope(pActor->GetEntity()->GetPhysics(), upperPos, lowerPos);
	
	m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate);

	return true;
}
//------------------------------------------------------------------------
Vec3 CVehicleViewFirstPerson::GetWorldPosGoal()
{
	Vec3 vehiclePos;

	if (m_pHelper)
	{
		vehiclePos = m_pHelper->GetVehicleSpaceTranslation();
	}
	else if(!m_sCharacterBoneName.empty())
	{
		Vec3 bonePos;
		IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_pSeat->GetPassenger());
		ICharacterInstance* pCharacter = pEntity ? pEntity->GetCharacter(0) : NULL;
		if(pCharacter)
		{
			IDefaultSkeleton& rIDefaultSkeleton = pCharacter->GetIDefaultSkeleton();
			uint32 id = rIDefaultSkeleton.GetJointIDByName(m_sCharacterBoneName);
			uint32 numJoints = rIDefaultSkeleton.GetJointCount();
			if(numJoints > id)
			{
				bonePos = pCharacter->GetISkeletonPose()->GetAbsJointByID(id).t;
			}
		}
		vehiclePos = pEntity ? pEntity->GetWorldTM() * bonePos : Vec3(0,0,0);	
		return vehiclePos;
	}
	else
	{
		IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(m_passengerId);
		CRY_ASSERT(pActor);

		vehiclePos = pActor->GetLocalEyePos() + m_offset;

		IEntity* pActorEntity = pActor->GetEntity();
		
		const Matrix34& slotTM = pActorEntity->GetSlotLocalTM(0, false);
    vehiclePos = pActorEntity->GetLocalTM() * slotTM * vehiclePos;
	}

	return m_pVehicle->GetEntity()->GetWorldTM() * vehiclePos;
}
Ejemplo n.º 25
0
int CFlowConvoyNode::GetCoachIndexPlayerIsOn()
{
	IPhysicalEntity *pGroundCollider=NULL;
	IActor *pPlayerActor = gEnv->pGame->GetIGameFramework()->GetClientActor();

	// if player use a mounted weapon on the train, the GroundCollider check not good
	if(m_coachIndex>=0)
	{//player can catch mounted weapon on the train if he were on it before
		CItem *pCurrentItem=static_cast<CItem *>(pPlayerActor->GetCurrentItem());
		if ( pCurrentItem != NULL && pCurrentItem->IsMounted()) 
			return m_coachIndex; // give back the last m_coachIndex, it should be valid 		
	}

	IPhysicalEntity *pPhysicalEntity=pPlayerActor->GetEntity()->GetPhysics();
	if (pPhysicalEntity)
	{
		pe_status_living livStat;
		if(pPhysicalEntity->GetStatus(&livStat))
			pGroundCollider=livStat.pGroundCollider;
	}
	
	if(!pGroundCollider)
		return -1;

	for (size_t i = 0; i < m_coaches.size(); ++i)
	{
		if(m_coaches[i].m_pEntity->GetPhysics()==pGroundCollider)
			return i;
		else
		{//attached objects
			IEntity *pCoachEntity=m_coaches[i].m_pEntity;
			for (int j = 0; j < pCoachEntity->GetChildCount(); ++j)
			{
				if(pCoachEntity->GetChild(j)->GetPhysics()==pGroundCollider)
					return i;
			}
		}
	}
	return -1;
}
Ejemplo n.º 26
0
void CHeavyMountedWeapon::InitClient(int channelId)
{
	CWeapon::InitClient(channelId); //Avoid calling CHeavyWeapon::InitClient as mounted weapons need special case logic to handle late joiners (Based on the ripoff state)

	if(m_rippingOff || m_rippedOff)
	{
		IActor *pActor = GetOwnerActor();
		if(pActor)
		{
			EntityId ownerID = pActor->GetEntity()->GetId();
			GetGameObject()->InvokeRMIWithDependentObject(ClRipOff(), BaseClass::SHeavyWeaponUserParams(ownerID), eRMI_ToClientChannel, ownerID, channelId);	
		}
		else
		{
			GetGameObject()->InvokeRMI(ClDropped(), EmptyParams(), eRMI_ToClientChannel, channelId);
		}
	}
	
	if(m_bIsHighlighted && !m_rippingOff)
	{
		GetGameObject()->InvokeRMI(ClHeavyWeaponHighlighted(), SNoParams(), eRMI_ToClientChannel, channelId);		 
	}
}
//------------------------------------------------------------------------
void CVehicleSeatActionPassengerIK::Update(float frameTime)
{
	if (!m_passengerId)
		return;

	IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(m_passengerId);
	if (!pActor)
	{
		CRY_ASSERT(!"Invalid entity id for the actor id, Actor System didn't know it");
		return;
	}

	if (ICharacterInstance* pCharInstance = pActor->GetEntity()->GetCharacter(0))
	{
		ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim();
		CRY_ASSERT(pSkeletonAnim);

		if (pSkeletonAnim->GetNumAnimsInFIFO(0) >= 1)
		{
			const CAnimation& anim = pSkeletonAnim->GetAnimFromFIFO(0, 0);
			const uint16 loopCount = anim.GetLoop();
			const f32 animationTime = pSkeletonAnim->GetAnimationNormalizedTime( &anim );
			if (!m_waitShortlyBeforeStarting || (loopCount > 0 || animationTime > 0.9f))
			{
				for (TIKLimbVector::iterator ite = m_ikLimbs.begin(); ite != m_ikLimbs.end(); ++ite)
				{
					const SIKLimb& limb = *ite;

					Vec3 helperPos = limb.pHelper->GetWorldSpaceTranslation();
					pActor->SetIKPos(limb.limbName.c_str(), helperPos, 1);
				}
			}
		}
	}

}
Ejemplo n.º 28
0
//-------------------------------------------
void CGameRules::ProcessClientExplosionScreenFX(const ExplosionInfo &explosionInfo)
{
	IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();
	if (pClientActor)
	{
		//Distance
		float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len();

		//Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80)
		CActor *pActor = (CActor *)pClientActor;
		SMovementState state;
		if (IMovementController *pMV = pActor->GetMovementController())
		{
			pMV->GetMovementState(state);
		}

		Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition;
		eyeToExplosion.Normalize();
		bool inFOV = (state.eyeDirection.Dot(eyeToExplosion) > 0.68f);
		
		// if in a vehicle eyeDirection is wrong
		if(pActor && pActor->GetLinkedVehicle())
		{
			Vec3 eyeDir = static_cast<CPlayer*>(pActor)->GetVehicleViewDir();
			inFOV = (eyeDir.Dot(eyeToExplosion) > 0.68f);
		}

		//All explosions have radial blur (default 30m radius, to make Sean happy =))
		float maxBlurDistance = (explosionInfo.maxblurdistance>0.0f)?explosionInfo.maxblurdistance:30.0f;
		if (maxBlurDistance>0.0f && g_pGameCVars->g_radialBlur>0.0f && m_explosionScreenFX && explosionInfo.radius>0.5f)
		{		
			if (inFOV && dist < maxBlurDistance)
			{
				ray_hit hit;
				int col = gEnv->pPhysicalWorld->RayWorldIntersection(explosionInfo.pos , -eyeToExplosion*dist, ent_static | ent_terrain, rwi_stop_at_pierceable|rwi_colltype_any, &hit, 1);

				//If there was no obstacle between flashbang grenade and player
				if(!col)
				{
					if (CScreenEffects* pSE = pActor->GetScreenEffects())
					{
						float blurRadius = (-1.0f/maxBlurDistance)*dist + 1.0f;

						gEnv->p3DEngine->SetPostEffectParam("FilterRadialBlurring_Radius", blurRadius);
						gEnv->p3DEngine->SetPostEffectParam("FilterRadialBlurring_Amount", 1.0f);

						IBlendedEffect *pBlur	= CBlendedEffect<CPostProcessEffect>::Create(CPostProcessEffect(pClientActor->GetEntityId(),"FilterRadialBlurring_Amount", 0.0f));
						IBlendType   *pLinear = CBlendType<CLinearBlend>::Create(CLinearBlend(1.0f));
						pSE->StartBlend(pBlur, pLinear, 1.0f, CScreenEffects::eSFX_GID_RBlur);
						pSE->SetUpdateCoords("FilterRadialBlurring_ScreenPosX","FilterRadialBlurring_ScreenPosY", explosionInfo.pos);
					}

					float distAmp = 1.0f - (dist / maxBlurDistance);
					if (gEnv->pInput) 
						gEnv->pInput->ForceFeedbackEvent( SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.5f, distAmp*3.0f, 0.0f));
				}
			}
		}

		//Flashbang effect 
		if(dist<explosionInfo.radius && inFOV &&
			(!strcmp(explosionInfo.effect_class,"flashbang") || !strcmp(explosionInfo.effect_class,"FlashbangAI")))
		{
			ray_hit hit;
			int col = gEnv->pPhysicalWorld->RayWorldIntersection(explosionInfo.pos , -eyeToExplosion*dist, ent_static | ent_terrain, rwi_stop_at_pierceable|rwi_colltype_any, &hit, 1);

			//If there was no obstacle between flashbang grenade and player
			if(!col)
			{
				float power = explosionInfo.flashbangScale;
				power *= max(0.0f, 1 - (dist/explosionInfo.radius));
				float lookingAt = (eyeToExplosion.Dot(state.eyeDirection.normalize()) + 1)*0.5f;
				power *= lookingAt;

				SAFE_GAMEAUDIO_SOUNDMOODS_FUNC(AddSoundMood(SOUNDMOOD_EXPLOSION,MIN(power*40.0f,100.0f)));

				gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", 1.0f + (power * 4));
				gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount",explosionInfo.blindAmount);
				gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", (power * 2));
				gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1);
			}
		}
		else if(inFOV && (dist < explosionInfo.radius))
		{
			if (explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f)
			{
				//Add some angular impulse to the client actor depending on distance, direction...
				float dt = (1.0f - dist/explosionInfo.radius);
				dt = dt * dt;
				float angleZ = gf_PI*0.15f*dt;
				float angleX = gf_PI*0.15f*dt;

				pActor->AddAngularImpulse(Ang3(Random(-angleX*0.5f,angleX),0.0f,Random(-angleZ,angleZ)),0.0f,dt*2.0f);
			}
		}


		float fDist2=(pClientActor->GetEntity()->GetWorldPos()-explosionInfo.pos).len2();
		if (fDist2<250.0f*250.0f)
		{		
			if (fDist2<sqr(SAFE_GAMEAUDIO_BATTLESTATUS_FUNC_RET(GetBattleRange())))
				SAFE_GAMEAUDIO_BATTLESTATUS_FUNC(TickBattleStatus(1.0f));
		}
	}

}
Ejemplo n.º 29
0
//--------------------------------------------------------------------------------------------------
// Name: SpawnScreenExplosionEffect
// Desc: Spawns screen explosion effect
//--------------------------------------------------------------------------------------------------
void CExplosionGameEffect::SpawnScreenExplosionEffect(const SExplosionContainer &explosionContainer)
{
	// Disclaimer: this code was originally from GameRulesClientServer::ProcessClientExplosionScreenFX()

	const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo;

	if(explosionInfo.pressure < 1.0f)
		return;

	IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();
	if(pClientActor != NULL && !pClientActor->IsDead())
	{
		CPlayer* pPlayer = static_cast<CPlayer*>(pClientActor);
		bool hasFlashBangEffect = explosionInfo.blindAmount > 0.0f;

		// Flashbang friends and self?...
		if(hasFlashBangEffect)
		{
			bool flashBangSelf = true;
			bool flashBangFriends = false;
#ifndef _RELEASE
			flashBangSelf = g_pGameCVars->g_flashBangSelf != 0;
			flashBangFriends = g_pGameCVars->g_flashBangFriends != 0;
#endif
			bool ownFlashBang = pPlayer->GetEntityId() == explosionInfo.shooterId;
			if((!flashBangSelf && ownFlashBang) || // FlashBang self?
				((g_pGame->GetGameRules()->GetFriendlyFireRatio()<=0.0f) && (!flashBangFriends) && (!ownFlashBang) && pPlayer->IsFriendlyEntity(explosionInfo.shooterId))) // FlashBang friends?
			{
				return;
			}
		}

		// Distance
		float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len();

		// Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80)
		SMovementState state;
		if(IMovementController *pMV = pClientActor->GetMovementController())
		{
			pMV->GetMovementState(state);
		}

		Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition;
		Vec3 eyeDir = pClientActor->GetLinkedVehicle() ? pPlayer->GetVehicleViewDir() : state.eyeDirection;
		eyeToExplosion.Normalize();
		float eyeDirectionDP = eyeDir.Dot(eyeToExplosion);
		bool inFOV = (eyeDirectionDP > 0.68f);

		// All explosions have radial blur (default 30m radius)
		const float maxBlurDistance = (explosionInfo.maxblurdistance >0.0f) ? explosionInfo.maxblurdistance : 30.0f;
		if((maxBlurDistance > 0.0f) && (g_pGameCVars->g_radialBlur > 0.0f) && (explosionInfo.radius > 0.5f))
		{		
			if (inFOV && (dist < maxBlurDistance))
			{
				const int intersectionObjTypes = ent_static | ent_terrain;
				const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any;

				m_deferredScreenEffects.RequestRayCast(CDeferredExplosionEffect::eDET_RadialBlur, 
														explosionInfo.pos, -eyeToExplosion, dist, maxBlurDistance, intersectionObjTypes, intersectionFlags, NULL, 0);
			}
		}

		// Flashbang effect 
		if(hasFlashBangEffect && ((dist < (explosionInfo.radius*g_pGameCVars->g_flashBangNotInFOVRadiusFraction)) 
			|| (inFOV && (dist < explosionInfo.radius))))
		{
			ray_hit hit;
			const int intersectionObjTypes = ent_static | ent_terrain;
			const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any;
			const int intersectionMaxHits = 1;

			int collision = gEnv->pPhysicalWorld->RayWorldIntersection(	explosionInfo.pos, 
																																	-eyeToExplosion*dist, 
																																	intersectionObjTypes, 
																																	intersectionFlags, 
																																	&hit, 
																																	intersectionMaxHits);

			// If there was no obstacle between flashbang grenade and player
			if(!collision)
			{
				bool enabled = true;
				if(enabled)
				{
					CCCPOINT (FlashBang_Explode_BlindLocalPlayer);
					float timeScale = max(0.0f, 1 - (dist/explosionInfo.radius));
					float lookingAt = max(g_pGameCVars->g_flashBangMinFOVMultiplier, (eyeDirectionDP + 1)*0.5f);

					float time = explosionInfo.flashbangScale * timeScale *lookingAt;	// time is determined by distance to explosion		

					CRY_ASSERT_MESSAGE(pClientActor->IsPlayer(),"Effect shouldn't be spawned if not a player");

					SPlayerStats* pStats = static_cast<SPlayerStats*>(pPlayer->GetActorStats());

					NET_BATTLECHATTER(BC_Blinded, pPlayer);

					if(pClientActor->GetEntityId() == explosionInfo.shooterId)
					{
						g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_BlindSelf);
					}
					else
					{
						g_pGame->GetGameRules()->SuccessfulFlashBang(explosionInfo, time);
					}

					pPlayer->StartFlashbangEffects(time, explosionInfo.shooterId);

					gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", time);
					gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount", explosionInfo.blindAmount);
					gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", time);
					gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1.0f);

					CRecordingSystem *pRecordingSystem = g_pGame->GetRecordingSystem();
					if (pRecordingSystem)
					{
						pRecordingSystem->OnPlayerFlashed(time, explosionInfo.blindAmount);
					}
				}
			}
			else
			{
				CCCPOINT (FlashBang_Explode_NearbyButBlockedByGeometry);
			}
		}
		else if(inFOV && (dist < explosionInfo.radius))
		{
			if(explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f)
			{
				// Add some angular impulse to the client actor depending on distance, direction...
				float dt = (1.0f - dist/explosionInfo.radius);
				dt = dt * dt;
				float angleZ = gf_PI*0.15f*dt;
				float angleX = gf_PI*0.15f*dt;

				if (pClientActor)
				{
					static_cast<CActor*>(pClientActor)->AddAngularImpulse(Ang3(cry_random(-angleX*0.5f,angleX),0.0f,cry_random(-angleZ,angleZ)),0.0f,dt*2.0f);
				}
			}
		}
	}
}//-------------------------------------------------------------------------------------------------
Ejemplo n.º 30
0
//------------------------------------------------------------------------
void CProjectile::Ricochet(EventPhysCollision *pCollision)
{
	IActor *pActor = g_pGame->GetIGameFramework()->GetClientActor();
	if (!pActor)
		return;

	Vec3 dir=pCollision->vloc[0];
	dir.NormalizeSafe();

	float dot=pCollision->n.Dot(dir);

	if (dot>=0.0f) // backface
		return;

	float b=0,f=0;
	uint matPierceability=0;
	if (!gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], b, f, matPierceability))
		return;

	matPierceability&=sf_pierceable_mask;
	float probability=0.25+0.25*(MAX(0,7-matPierceability)/7.0f);
	if ((matPierceability && matPierceability>=8) || Random()>probability)
		return;

	f32 cosine = dir.Dot(-pCollision->n);
	if (cosine>1.0f)cosine=1.0f;
	if (cosine<-1.0f)	cosine=-1.0f;
	float angle=RAD2DEG( cry_fabsf(cry_acosf(cosine)) );
	if (angle<10.0f)
		return;

	Vec3 ricochetDir = -2.0f*dot*pCollision->n+dir;
	ricochetDir.NormalizeSafe();

	Ang3 angles=Ang3::GetAnglesXYZ(Matrix33::CreateRotationVDir(ricochetDir));

	float rx=Random()-0.5f;
	float rz=Random()-0.5f;

	angles.x+=rx*DEG2RAD(10.0f);
	angles.z+=rz*DEG2RAD(10.0f);

	ricochetDir=Matrix33::CreateRotationXYZ(angles).GetColumn(1).normalized();

	Lineseg line(pCollision->pt, pCollision->pt+ricochetDir*20.0f);
	Vec3 player = pActor->GetEntity()->GetWorldPos();

	float t;
	float distanceSq=Distance::Point_LinesegSq(player, line, t);

	if (distanceSq < 7.5*7.5 && (t>=0.0f && t<=1.0f))
	{
		if (distanceSq >= 0.25*0.25)
		{
			Sphere s;
			s.center = player;
			s.radius = 6.0f;

			Vec3 entry,exit;
			int intersect=Intersect::Lineseg_Sphere(line, s, entry,exit);
			if (intersect) // one entry or one entry and one exit
			{
				if (intersect==0x2)
					entry=pCollision->pt;
				RicochetSound(entry, ricochetDir);

				//gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(entry, ColorB(255, 255, 255, 255), entry+ricochetDir, ColorB(255, 255, 255, 255), 2);
			}
		}
	}
}