void ScreenLayoutManager::UpdateHUDCanvasSize( void )
{
	const int renderWidth = gEnv->pRenderer->GetWidth();
	const int renderHeight = gEnv->pRenderer->GetHeight();
	RENDER_SCREEN_WIDTH = (float)renderWidth;
	RENDER_SCREEN_HEIGHT = (float)renderHeight;

	assert(RENDER_SCREEN_WIDTH>0.0f);
	assert(RENDER_SCREEN_HEIGHT>0.0f);
	INV_RENDER_SCREEN_WIDTH = 1.0f*__fres(RENDER_SCREEN_WIDTH);
	INV_RENDER_SCREEN_HEIGHT = 1.0f*__fres(RENDER_SCREEN_HEIGHT);

	// Force update of HUDAssets and other objects.
	const float pa = gEnv->pRenderer->GetPixelAspectRatio();
	Vec2 curCanvasSize( RENDER_SCREEN_WIDTH*__fres(pa), RENDER_SCREEN_HEIGHT );








	SHUDEvent resizeEvent(eHUDEvent_OnResolutionChange);
	resizeEvent.AddData(SHUDEventData(curCanvasSize.x));
	resizeEvent.AddData(SHUDEventData(curCanvasSize.y));
	resizeEvent.AddData(SHUDEventData(RENDER_SCREEN_WIDTH));
	resizeEvent.AddData(SHUDEventData(RENDER_SCREEN_HEIGHT));
	resizeEvent.AddData(SHUDEventData(int_round(RENDER_SCREEN_WIDTH)));
	resizeEvent.AddData(SHUDEventData(int_round(RENDER_SCREEN_HEIGHT)));
	//resizeEvent.AddData(SHUDEventData(pa));
	CHUDEventDispatcher::CallEvent(resizeEvent);

}
//------------------------------------------------------------------------
float CGameRulesCommonDamageHandling::GetVehicleForeignCollisionMultiplier( const IVehicle& vehicle, const SCollisionEntityInfo& colliderInfo, const CGameRules::SCollisionHitInfo& colHitInfo ) const
{
	float result = 1.0f;
	
	//Vehicle to vehicle collision
	if (colliderInfo.pEntityVehicle)
	{
		const float vehicleMass = vehicle.GetMass();
		const float vehicleColliderMass = colliderInfo.pEntityVehicle->GetMass();

		const float targetSpeedSqr = colHitInfo.target_velocity.len2();

		if ((vehicleMass > vehicleColliderMass * 1.5f) && (targetSpeedSqr > 0.01f))
		{
			//Reduce damage for collisions with large mass ratios, to avoid instant-killing
			const float ratio = 1.0f + (0.35f * min(10.0f, vehicleMass * __fres(vehicleColliderMass))) * min(1.0f, targetSpeedSqr * 0.31623f);
			result = __fres(ratio);

			if (DebugCollisions())
			{
				CryLog("Vehicle/Vehicle (%s <- %s), collision mult: %.2f", vehicle.GetEntity()->GetName(), colliderInfo.pEntity->GetName(), result);
			}
		}
	}

	return result;
}
void CRecoil::PatchSpreadMod(const SSpreadModParams& spreadMod, const SSpreadParams& originalSpreadParams, float modMultiplier)
{
	float oldSpreadMin = m_spreadParams.min;
	float oldSpreadMax = m_spreadParams.max;

	m_spreadParams.attack											= CalculateParamModValue(originalSpreadParams.attack, spreadMod.attack_mod, modMultiplier);
	m_spreadParams.decay											= CalculateParamModValue(originalSpreadParams.decay, spreadMod.decay_mod, modMultiplier);
	m_spreadParams.end_decay									= CalculateParamModValue(originalSpreadParams.end_decay, spreadMod.end_decay_mod, modMultiplier);
	m_spreadParams.max												= CalculateParamModValue(originalSpreadParams.max, spreadMod.max_mod, modMultiplier);
	m_spreadParams.min												= CalculateParamModValue(originalSpreadParams.min, spreadMod.min_mod, modMultiplier);
	m_spreadParams.rotation_m									= CalculateParamModValue(originalSpreadParams.rotation_m, spreadMod.rotation_m_mod, modMultiplier);
	m_spreadParams.speed_m										= CalculateParamModValue(originalSpreadParams.speed_m, spreadMod.speed_m_mod, modMultiplier);
	m_spreadParams.speed_holdBreathActive_m		= CalculateParamModValue(originalSpreadParams.speed_holdBreathActive_m, spreadMod.speed_holdBreathActive_m_mod, modMultiplier);
	m_spreadParams.spread_crouch_m						= CalculateParamModValue(originalSpreadParams.spread_crouch_m, spreadMod.spread_crouch_m_mod, modMultiplier);
	m_spreadParams.spread_jump_m							= CalculateParamModValue(originalSpreadParams.spread_jump_m, spreadMod.spread_jump_m_mod, modMultiplier);
	m_spreadParams.spread_slide_m							= CalculateParamModValue(originalSpreadParams.spread_slide_m, spreadMod.spread_slide_m_mod, modMultiplier);
	m_spreadParams.spread_holdBreathActive_m	= CalculateParamModValue(originalSpreadParams.spread_holdBreathActive_m, spreadMod.spread_holdBreathActive_m_mod, modMultiplier);

	float oldSpreadRange = oldSpreadMax-oldSpreadMin;
	if(oldSpreadRange)
	{
		float inverseOldSpreadRange = __fres(oldSpreadRange);
		float ratio = ((m_spread-oldSpreadMin) * inverseOldSpreadRange);
		m_spread = m_spreadParams.min + (m_spreadParams.max-m_spreadParams.min) * ratio;
	}
	else
	{
		m_spread = m_spreadParams.min;
	}

	m_useSpreadMultiplier = false;
}
void CWeapon::EndVerificationSample(IActor * pActor, uint32 oldShotId)
{
    if(m_fSampleNumShots > 1.0f)	//This check needs to be here as some calls will call this directly
    {   //	without calling ShouldEndVerificationSample()
        const float fSampleStartTime = m_fSampleStartTime;

        const INetChannel*  pNetChannel = gEnv->pGame->GetIGameFramework()->GetNetChannel(pActor->GetChannelId());
        const float  fNetLag = ((pActor->IsClient() || !pNetChannel) ? 0 : (pNetChannel->GetPing(true)));  // GetPing() is the round journey but we're giving some leeway

        //work out how long the sample covered.
        //TODO: Work out if we need latency compensation here?
        const float kServerFrameTime		= gEnv->pTimer->GetFrameTime();
        const float kAdditionalFudge		= (kServerFrameTime * 2.0f) + (fNetLag * 2.0f);	//Generously assume that their ping could spike significantly
        const float fActualSampleLength = (m_fLastSampleTakenTime - fSampleStartTime) + kAdditionalFudge;

        const float fFireRate = m_fSampleNumShots / fActualSampleLength;

        const int kCurrentFireModeIdx = (oldShotId & CWeapon::GetShotIdFireModeMask()) >> CWeapon::GetShotIdFireModeOffset();
        CFireMode * pFireMode = static_cast<CFireMode*>(GetFireMode(kCurrentFireModeIdx));
        if(pFireMode)
        {
            //Fire rate is in shots per minute, convert to shots per second
            float fMaxFireRate = pFireMode->GetFireRate() * ( 1.0f / 60.0f );
            if(pActor->IsPlayer())
            {
                fMaxFireRate *= __fres(pFireMode->GetTimeBetweenShotsMultiplier(static_cast<CPlayer*>(pActor)));
            }

            if(fFireRate > fMaxFireRate)
            {
                g_pGame->GetAntiCheatManager()->FlagActivity(eCT_FireRate, pActor->GetChannelId(), fFireRate / fMaxFireRate, GetEntity()->GetName());
            }
        }
    }
}
示例#5
0
//---------------------------------------------------------------
void CPlayerRotation::ProcessNormalRoll( float frameTime )
{
	//apply lean/roll
	float rollAngleGoal(0);
	const Vec3 velocity = m_player.GetActorPhysics().velocity;
	const float speed2( velocity.len2());

	if ((speed2 > 0.01f) && m_player.m_stats.inAir)
	{
		
		const float maxSpeed = m_player.GetStanceMaxSpeed(STANCE_STAND);
		const float maxSpeedInverse = (float)__fsel(-maxSpeed, 1.0f, __fres(maxSpeed + FLT_EPSILON));
	
		const Vec3 velVec = velocity * maxSpeedInverse;

		const float dotSide(m_viewQuat.GetColumn0() * velVec);

		rollAngleGoal -= DEG2RAD(dotSide * 1.5f);;
	}

	const float tempLean = m_leanAmount;
	const float leanAmountMultiplier = 3.0f;
	const float leanAmount = clamp_tpl(tempLean * leanAmountMultiplier, -1.0f, 1.0f);
	
	rollAngleGoal += DEG2RAD(leanAmount * m_player.m_params.leanAngle);
	Interpolate(m_viewRoll,rollAngleGoal,9.9f,frameTime);

	m_deltaAngles += m_angularImpulseDelta;
}
示例#6
0
void CPlayerRotation::ProcessForcedLookDirection( const Quat& lastViewQuat, float frameTime )
{
	const float forceLookLenSqr(m_forceLookVector.len2());
	
	if (forceLookLenSqr < 0.001f)
		return;
	
	const float forceLookLen(sqrt_tpl(forceLookLenSqr));
	Vec3 forceLook(m_forceLookVector);
	forceLook *= (float)__fres(forceLookLen);
	forceLook = lastViewQuat.GetInverted() * forceLook;

	const float smoothSpeed(6.6f * forceLookLen);

	float blendAmount = min(1.0f,frameTime*smoothSpeed);
	if(!m_bForcedLookAtBlendingEnabled)
	{
		blendAmount = 1.0f; 
	}

	m_deltaAngles.x += asinf(forceLook.z) * blendAmount;
	m_deltaAngles.z += atan2_tpl(-forceLook.x,forceLook.y) * blendAmount;

	PR_CHECKQNAN_VEC(m_deltaAngles);
}
float CGameRulesRSSpawning::GetScoreFromProximityToEnemies( SUsefulSpawnData& spawnData, TPositionList& EnemyPlayerPositions, const Vec3& potentialSpawnPosition )
{
	SpawnLogAlways("[SPAWN] > GetScoreFromProximityToEnemies()");
	float fScoreFromEnemies = 0.0f;

	if(spawnData.numActiveEnemyPlayers > 0)
	{
		const float fScoreOnTopOfEnemy = 200.0f;
		const float fMultiplierForEnemyDistance = 1.7f;
		const float fDistanceScoreMultiplier = 200.0f;

		for(int i = EnemyPlayerPositions.size() - 1; i >= 0; i--)
		{
			Vec3  vDiffToEnemy			 = (EnemyPlayerPositions[i] - potentialSpawnPosition);
			vDiffToEnemy.z += max(2.0f * vDiffToEnemy.z, 6.0f);
			float fDistanceFromEnemy = vDiffToEnemy.len();

			float fDistanceScoreFraction = __fres(max(fDistanceFromEnemy - 4.f, 0.001f));

			float fScoreForThisEnemy = max(fScoreOnTopOfEnemy - (fDistanceFromEnemy * fMultiplierForEnemyDistance), 0.0f) + (fDistanceScoreFraction * fDistanceScoreMultiplier);

			SpawnLogAlways("[SPAWN] >>> Score from Enemy %d is %.6f at distance %.1f", i, fScoreForThisEnemy, fDistanceFromEnemy);

			fScoreFromEnemies = max(fScoreForThisEnemy, fScoreFromEnemies);
		}

		SpawnLogAlways("[SPAWN] >> Total Score from Enemies: %.6f", fScoreFromEnemies);
	}

	return fScoreFromEnemies;
}
////////////////////////////////////////////////
// This is currently identical to the GetEnemyTeamCentre function,
//	but functionality will change in the future
void CGameRulesRSSpawning::GetFriendlyTeamCentre( SUsefulSpawnData& spawnData, Vec3 * pOutCentre )
{
	int				idx								= 0;
	EntityId	friendlyPlayerId	= 0;

	float fNumFriendlies				= 0.0f;
	Vec3	pureAveragePosition(0.0f, 0.0f, 0.0f);

	while( friendlyPlayerId = m_pGameRules->GetTeamActivePlayer(spawnData.playerTeamId, idx++))
	{
		fNumFriendlies += 1.0f;

		const IEntity * pFriendlyPlayer = gEnv->pEntitySystem->GetEntity(friendlyPlayerId);

		Vec3 friendlyPosition = pFriendlyPlayer->GetPos();

		float fInvNumFriendlies					= __fres(fNumFriendlies);
		float fCurrentPositionWeighting = 1.0f - fInvNumFriendlies;

		//This is slightly more computationally expensive than adding them all up, but 
		//	avoids the potential for some float precision problems
		pureAveragePosition = (pureAveragePosition * fCurrentPositionWeighting) + (fInvNumFriendlies * friendlyPosition);
	}

	*pOutCentre = pureAveragePosition;
}
void EntityEffects::CHeatController::AddHeatPulse( const float intensity, const float time )
{
	const float currentPulseHeat = (float)__fsel(-m_heatPulse.baseTime, 
		0.0f, 
		clamp((1.0f - (m_heatPulse.runningTime * (float)__fres(m_heatPulse.baseTime + FLT_EPSILON))) * m_heatPulse.heat, 0.0f, 1.0f));
	m_heatPulse.heat = clamp(currentPulseHeat + intensity, 0.0f, 1.0f - m_baseHeat);
	m_heatPulse.baseTime = clamp((m_heatPulse.baseTime - m_heatPulse.runningTime) + time, 0.0f, 4.5f);	//Fixed to maximum of 4.5secs to cool down
	m_heatPulse.runningTime = 0.0f;
}
示例#10
0
void CPlayerStateJump::FinalizeVelocity( CPlayer& player, const Vec3& newVelocity )
{
	const float fNewSpeed = newVelocity.len();

	const float fVelocityMultiplier = (float)__fsel(fNewSpeed - 22.0f, __fres(fNewSpeed+FLT_EPSILON) * 22.0f, 1.0f);

	// TODO: Maybe we should tell physics about this new velocity ? Or maybe SPlayerStats::velocity ? (stephenn).
	player.GetMoveRequest().velocity = newVelocity * fVelocityMultiplier;
}
	void Update(IEntity &entity, float timePassed)
	{
		if (m_invalid)
			return;

		QuatT applyingDelta(IDENTITY);

		const float newTime   = min(m_lastTime + timePassed, m_targetTime);
		const float deltaTime = newTime - m_lastTime;
		if (deltaTime > 0.0f)
		{
			Quat totalDeltaRot, lastTotalDeltaRot;

			const float targetTimeInverse = (float)__fres(m_targetTime);

			const float dt = deltaTime * targetTimeInverse;

			const float t     = newTime * targetTimeInverse;
			const float lastT = m_lastTime * targetTimeInverse;

			totalDeltaRot.SetSlerp(Quat(IDENTITY), m_deltaRot, t);
			lastTotalDeltaRot.SetSlerp(Quat(IDENTITY), m_deltaRot, lastT);

			applyingDelta.q = (!lastTotalDeltaRot * totalDeltaRot);
			applyingDelta.t = (m_delta * dt);

			m_lastTime = newTime;
		}
		else if (m_targetTime == 0.f)
		{
			applyingDelta.t = m_delta;
			applyingDelta.q = m_deltaRot;
			m_invalid       = true;
		}

		//CryLog("Moving %s from (%f, %f, %f) to (%f, %f, %f) delta (%f, %f, %f) timeDelta: %f time: %f timeTgt: %f",
		//			entity.GetName(),
		//			entity.GetPos().x, entity.GetPos().y, entity.GetPos().z,
		//			(entity.GetPos()+applyingDelta.t).x, (entity.GetPos()+applyingDelta.t).y, (entity.GetPos()+applyingDelta.t).z,
		//			applyingDelta.t.x, applyingDelta.t.y, applyingDelta.t.z,
		//			deltaTime, newTime, m_targetTime);

		if (m_pAnimatedCharacter)
		{
			m_pAnimatedCharacter->ForceMovement(applyingDelta);
		}
		else
		{
			if (IEntity* pParent = entity.GetParent())
				applyingDelta.t = !pParent->GetRotation() * applyingDelta.t;

			entity.SetPosRotScale(entity.GetPos() + applyingDelta.t, entity.GetRotation() * applyingDelta.q, entity.GetScale());
		}
	}
void CGameRulesRSSpawning::UpdateSpawnPointAverage(const EntityId spawnId, float& fNumSpawns, Vec3& averagePos) const
{
	fNumSpawns += 1.0f;

	const IEntity *pSpawn = gEnv->pEntitySystem->GetEntity(spawnId);

	Vec3 spawnPosition = pSpawn->GetPos();

	float fInvNumSpawns = __fres(fNumSpawns);
	float fScaleRemainder = 1.0f - fInvNumSpawns;

	averagePos = (spawnPosition * fInvNumSpawns) + (averagePos * fScaleRemainder);
}
示例#13
0
void CPlayerRotation::ProcessAngularImpulses( float frameTime )
{
	//update angular impulse
	if (m_angularImpulseTime>0.001f)
	{
		m_angularImpulse *= min(m_angularImpulseTime * __fres(m_angularImpulseTimeMax), 1.0f);
		m_angularImpulseTime -= frameTime;
	}
	else if (m_angularImpulseDeceleration>0.001f)
	{
		Interpolate(m_angularImpulse,ZERO,m_angularImpulseDeceleration, frameTime);
	}
	m_angularImpulseDelta -= m_angularImpulse;
}
示例#14
0
void CPlayerRotation::ProcessLeanAndPeek( const SActorFrameMovementParams& movement )
{
	const float leanAmt = (float)__fsel(0.01f - fabsf(movement.desiredLean), 0.0f, movement.desiredLean);

	m_leanAmount = leanAmt;

	//check if its possible
	if ((leanAmt*leanAmt) < 0.01f)
	{
		m_leanAndPeekInfo.Reset();	//Clear any previous result
	}
	else
	{
		const EStance stance = m_player.GetStance();
		const float noLean(0.0f);
		const Vec3 playerPosition = m_player.GetEntity()->GetWorldPos();
		const Vec3 headPos(playerPosition + m_baseQuat * m_player.GetStanceViewOffset(stance,&noLean));
		const Vec3 newPos(playerPosition + m_baseQuat * m_player.GetStanceViewOffset(stance,&m_leanAmount));

		/*gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(headPos, 0.05f, ColorB(0,0,255,255) );
		gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(newPos, 0.05f, ColorB(0,0,255,255) );
		gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(headPos, ColorB(0,0,255,255), newPos, ColorB(0,0,255,255));*/

		const int rayFlags(rwi_stop_at_pierceable|rwi_colltype_any);
		IPhysicalEntity *pSkip(m_player.GetEntity()->GetPhysics());

		const float distMult(3.0f);
		const float distMultInv(1.0f/distMult);

		const Vec3& limitPoint = m_leanAndPeekInfo.GetLeanLimit(headPos + m_viewQuat.GetColumn1() * 0.25f, (newPos - headPos)*distMult, ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid, rayFlags, &pSkip, pSkip ? 1 : 0);

		const bool validHit = (!limitPoint.IsZero());
		if (validHit)
		{
			const float dist((headPos - newPos).len2() * distMult);
			const float invDist = dist>0.f ? __fres(dist) : 0.f;
			m_leanAmount *= ((limitPoint - headPos).len2() * invDist * distMultInv);

			//gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(hit.pt, 0.05f, ColorB(0,255,0,255) );
		}
	}

	// TODO(Márcio): Maybe do some checks here!
	m_peekOverAmount = movement.desiredPeekOver;
}
示例#15
0
void CDeferredExplosionEffect::TriggerRadialBlur( const Vec3& radialBlurCenter, float maxBlurDistance, float distance )
{
	CRY_ASSERT(maxBlurDistance > 0.0f);

	const float maxBlurDistanceInv = __fres(maxBlurDistance);

	if(CScreenEffects* pScreenFX = g_pGame->GetScreenEffects())
	{
		const float blurRadius = (-maxBlurDistanceInv * distance) + 1.0f;
		pScreenFX->ProcessExplosionEffect(blurRadius, radialBlurCenter);
	}

	const float distAmp = 1.0f - (distance * maxBlurDistanceInv);

	IForceFeedbackSystem* pForceFeedback = g_pGame->GetIGameFramework()->GetIForceFeedbackSystem();
	const ForceFeedbackFxId effectId = pForceFeedback->GetEffectIdByName("explosion");
	SForceFeedbackRuntimeParams ffParams(distAmp * 3.0f, 0.0f);
	pForceFeedback->PlayForceFeedbackEffect(effectId, ffParams);
	
}
float EntityEffects::CHeatController::UpdateHeat( const float frameTime )
{
	m_heatPulse.runningTime += frameTime;

	const float pulseFraction = clamp(m_heatPulse.runningTime * (float)__fres(m_heatPulse.baseTime), 0.0f, 1.0f);
	const bool pulseActive = (pulseFraction < 1.0f);

	float pulseHeat = 0.0f;

	if (pulseActive)
	{
		pulseHeat = (m_heatPulse.heat * (1.0f - pulseFraction));	
	}
	else
	{
		m_heatPulse.Reset();
	}

	return clamp(m_baseHeat + pulseHeat, 0.0f, 1.0f);
}
float CGameRulesRSSpawning::GetScoreFromProximityToEnemiesNoTeams( SUsefulSpawnData& spawnData, const Vec3& potentialSpawnPosition )
{
	SpawnLogAlways("[SPAWN] > GetScoreFromProximityToEnemiesNoTeams()");
	float fScoreFromEnemies = 0.0f;

	CGameRules::TPlayers players;
	g_pGame->GetGameRules()->GetPlayers(players);

	if(players.size() > 1)
	{
		const float fScoreOnTopOfEnemy = 200.0f;
		const float fMultiplierForEnemyDistance = 1.7f;
		const float fDistanceScoreMultiplier = 200.0f;
		int i = -1;

		for(CGameRules::TPlayers::iterator it=players.begin();it!=players.end();++it)
		{
			i++;

			if(*it == spawnData.playerId)
				continue;

			const IEntity *pOther = gEnv->pEntitySystem->GetEntity(*it);
			Vec3  vDiffToEnemy			 = (pOther->GetWorldPos() - potentialSpawnPosition);
			vDiffToEnemy.z					+= max(2.0f * vDiffToEnemy.z, 6.0f);
			float fDistanceFromEnemy = vDiffToEnemy.len();
			
			float fDistanceScoreFraction = __fres(max(fDistanceFromEnemy - 4.f, 0.001f));

			float fScoreForThisEnemy = max(fScoreOnTopOfEnemy - (fDistanceFromEnemy * fMultiplierForEnemyDistance), 0.0f) + (fDistanceScoreFraction * fDistanceScoreMultiplier);

			SpawnLogAlways("[SPAWN] >>> Score from Enemy %d is %.6f at distance %.1f", i, fScoreForThisEnemy, fDistanceFromEnemy);

			fScoreFromEnemies = max(fScoreForThisEnemy, fScoreFromEnemies);
		}

		SpawnLogAlways("[SPAWN] >> Total Score from Enemies: %.6f", fScoreFromEnemies);
	}

	return fScoreFromEnemies;
}
void CGameRulesRSSpawning::GetEnemyTeamCentre( SUsefulSpawnData& spawnData, Vec3 * pOutCentre )
{
	//This is now a blueprint for switching over the other functions to use the CActorManager.
	//	They are not being switched over now because there are more significant changes in MPTrunk
	//	that further changes would conflict with - Rich S

	int				idx						= 0;
	EntityId	enemyPlayerId = 0;

	float fNumEnemies				= 0.0f;
	Vec3	pureAveragePosition(0.0f, 0.0f, 0.0f);

	CActorManager * pActorManager = CActorManager::GetActorManager();
	
	pActorManager->PrepareForIteration();

	const int kNumActors = pActorManager->GetNumActors();

	for(int i = 0; i < kNumActors; i++)
	{
		SActorData actorData;
		pActorManager->GetNthActorData(i, actorData);

		if(actorData.teamId == spawnData.enemyTeamId && actorData.spectatorMode == CActor::eASM_None)
		{
			fNumEnemies += 1.0f;

			float fInvNumEnemies						= __fres(fNumEnemies);
			float fCurrentPositionWeighting = 1.0f - fInvNumEnemies;

			//This is slightly more computationally expensive than adding them all up, but 
			//	avoids the potential for some float precision problems
			pureAveragePosition = (pureAveragePosition * fCurrentPositionWeighting) + (fInvNumEnemies * actorData.position);
		}		
	}

	*pOutCentre = pureAveragePosition;
}
void CRecoil::UpdateRecoil(float recoilScale, float maxRecoil, bool weaponFired, bool weaponFiring, float frameTime)
{
	if (m_recoil_time > 0.0f)
	{
		m_recoil_time -= frameTime;
		m_recoil += (m_attack * frameTime) / m_recoilParams.recoil_time;
	}

	const bool isFiring = m_singleShot ? weaponFired : weaponFiring;
	const float decay = isFiring ? m_recoilParams.decay : m_recoilParams.end_decay;
	const float frameDecay = (float)__fsel(-decay, 0.0f, frameTime * recoilScale * maxRecoil * __fres(decay+FLT_EPSILON));
	m_recoil = clamp(m_recoil - frameDecay, 0.0f, maxRecoil);

	const float t = (float)__fsel(-maxRecoil, 0.0f, m_recoil * __fres(maxRecoil+FLT_EPSILON));
	const Vec3 new_offset = Vec3(
		m_recoil_dir.x * sin_tpl(DEG2RAD(m_recoilParams.max.x)),
		m_recoil_dir.y * sin_tpl(DEG2RAD(m_recoilParams.max.y)),
		m_recoil_dir.z) * t;

	m_recoil_offset = (new_offset * 0.66f) + (m_recoil_offset * 0.33f);

	CRecoilDebugDraw::DebugRecoil(t, m_recoil_offset);
}
CForceFeedBackSystem::SFFOutput CForceFeedBackSystem::SActiveEffect::Update( float frameTime )
{
	SFFOutput effectFF;

	bool canPlay = (runtimeParams.delay <= 0.0f);

	if (canPlay)
	{
		bool isLoopingEffect = (effectTime <= 0.0f); 

		const float effectTimeInv = !isLoopingEffect ? (float)__fres(effectTime) : 1.0f;
		const float sampleTime = runningTime * effectTimeInv;

		const float sampleTimeAAtFreq = sampleTime * frequencyA;
		const float sampleTimeAAtFreqNorm = clamp_tpl(sampleTimeAAtFreq - floor_tpl(sampleTimeAAtFreq), 0.0f, 1.0f);

		const float sampleTimeBAtFreq = sampleTime * frequencyB;
		const float sampleTimeBAtFreqNorm = clamp_tpl(sampleTimeBAtFreq - floor_tpl(sampleTimeBAtFreq), 0.0f, 1.0f);

		effectFF.forceFeedbackA = m_patternA.SamplePattern(sampleTimeAAtFreqNorm) * m_envelopeA.SampleEnvelope(sampleTime) * runtimeParams.intensity;
		effectFF.forceFeedbackB = m_patternB.SamplePattern(sampleTimeBAtFreqNorm) * m_envelopeB.SampleEnvelope(sampleTime) * runtimeParams.intensity;
		runningTime += frameTime;

		//Re-start the loop
		if (isLoopingEffect)
		{
			runningTime = (float)__fsel(1.0f - runningTime, runningTime, 0.0f);
		}
	}
	else
	{
		runtimeParams.delay = clamp_tpl(runtimeParams.delay - frameTime, 0.0f, runtimeParams.delay);
	}


	return effectFF;
}
//------------------------------------------------------------------------
void CRapid::Update(float frameTime, uint32 frameId)
{
	FUNCTION_PROFILER( GetISystem(), PROFILE_GAME );

	PlayStopRapidFireIfNeeded();

	BaseClass::Update(frameTime, frameId);

	if (m_speed <= 0.0f && m_acceleration < 0.0001f)
	{
		FinishDeceleration();
		return;
	}

	CActor* pOwnerActor = m_pWeapon->GetOwnerActor();
	const bool isOwnerClient = pOwnerActor ? pOwnerActor->IsClient() : false;
	const bool isOwnerPlayer = pOwnerActor ? pOwnerActor->IsPlayer() : false;

	m_pWeapon->RequireUpdate(eIUS_FireMode);

	m_speed = m_speed + m_acceleration*frameTime;

	if (m_speed > m_fireParams->rapidparams.max_speed)
	{
		m_speed = m_fireParams->rapidparams.max_speed;
		m_rapidFlags &= ~eRapidFlag_accelerating;
	}

	if ((m_speed >= m_fireParams->rapidparams.min_speed) && !(m_rapidFlags & eRapidFlag_decelerating))
	{
		float dt = 1.0f;
		if (cry_fabsf(m_speed)>0.001f && cry_fabsf(m_fireParams->rapidparams.max_speed)>0.001f)
		{
			dt = m_speed * (float)__fres(m_fireParams->rapidparams.max_speed);
		}
		CRY_ASSERT(m_fireParams->fireparams.rate > 0);
		
		m_next_shot_dt = 60.0f* (float)__fres((m_fireParams->fireparams.rate*dt));

		if (CanFire(false))
		{
			if (!OutOfAmmo())
			{
				const bool firing = (m_rapidFlags & eRapidFlag_netShooting) || Shoot(true, m_fireParams->fireparams.autoReload);
				Firing(firing);
			}
			else
			{
				StopFire();
			}
		}
	}
	else if (m_firing)
	{
		StopFire();
		if (OutOfAmmo() && isOwnerPlayer)
		{
			m_pWeapon->Reload();
		}
	}

	if ((m_speed < m_fireParams->rapidparams.min_speed) && (m_acceleration < 0.0f) && !(m_rapidFlags & eRapidFlag_decelerating))
		Accelerate(m_fireParams->rapidparams.deceleration);

	UpdateRotation(frameTime);
	UpdateFiring(pOwnerActor, isOwnerClient, isOwnerPlayer, frameTime);
}
示例#22
0
void CPlayerStateUtil::ApplyFallDamage( CPlayer& player, const float startFallingHeight, const float fHeightofEntity )
{
	CRY_ASSERT(player.IsClient());

	// Zero downwards impact velocity used for fall damage calculations if player was in water within the last 0.5 seconds.
	// Strength jumping straight up and down should theoretically land with a safe velocity, 
	// but together with the water surface stickyness the velocity can sometimes go above the safe impact velocity threshold.

	// DEPRECATED: comment left for prosterity in case dedicated server problems re-appear (author cannot test it).
	// On dedicated server the player can still be flying this frame as well, 
	// since synced pos from client is interpolated/smoothed and will not land immediately,
	// even though the velocity is set to zero.
	// Thus we need to use the velocity change instead of landing to identify impact.

	// DT: 12475: Falling a huge distance to a ledge grab results in no damage.
	// Now using the last velocity because when ledge grabbing the velocity is unchanged for this frame, thus zero damage is applied.
	// Assuming this a physics lag issue, using the last good velocity should be more-or-less ok.
	const float downwardsImpactSpeed = -(float)__fsel(-(player.m_playerStateSwim_WaterTestProxy.GetSwimmingTimer() + 0.5f), player.GetActorPhysics().velocityUnconstrainedLast.z, 0.0f);

	const SPlayerStats& stats = *player.GetActorStats();

	CRY_ASSERT(NumberValid(downwardsImpactSpeed));
	const float MIN_FALL_DAMAGE_DISTANCE = 3.0f;
	const float fallDist = startFallingHeight - fHeightofEntity;
	if ((downwardsImpactSpeed > 0.0f) && (fallDist > MIN_FALL_DAMAGE_DISTANCE))
	{
		const SPlayerHealth& healthCVars = g_pGameCVars->pl_health;

		float velSafe = healthCVars.fallDamage_SpeedSafe;
		float velFatal = healthCVars.fallDamage_SpeedFatal;
		float velFraction = (float)__fsel(-(velFatal - velSafe), 1.0f , (downwardsImpactSpeed - velSafe) * (float)__fres(velFatal - velSafe));

		CRY_ASSERT(NumberValid(velFraction));

		if (velFraction > 0.0f)
		{
			//Stop crouching after taking falling damage
			if(player.GetStance() == STANCE_CROUCH)
			{
				static_cast<CPlayerInput*>(player.GetPlayerInput())->ClearCrouchAction();
			}

			velFraction = powf(velFraction, gEnv->bMultiplayer ? healthCVars.fallDamage_CurveAttackMP : healthCVars.fallDamage_CurveAttack);

			const float maxHealth = player.GetMaxHealth();
			const float currentHealth  = player.GetHealth();

			HitInfo hit;
			hit.dir.zero();
			hit.type = CGameRules::EHitType::Fall;
			hit.shooterId = hit.targetId = hit.weaponId = player.GetEntityId();

			const float maxDamage = (float)__fsel(velFraction - 1.0f, maxHealth, max(0.0f, (gEnv->bMultiplayer?maxHealth:currentHealth) - healthCVars.fallDamage_health_threshold));

			hit.damage = velFraction * maxDamage;

			g_pGame->GetGameRules()->ClientHit(hit);

#ifdef PLAYER_MOVEMENT_DEBUG_ENABLED
			player.GetMovementDebug().LogFallDamage(player.GetEntity(), velFraction, downwardsImpactSpeed, hit.damage);
		}
		else
		{
			player.GetMovementDebug().LogFallDamageNone(player.GetEntity(), downwardsImpactSpeed);
		}
#else
		}
#endif
	}
void CPlayerPlugin_InteractiveEntityMonitor::Update( const float dt )
{
	m_timeUntilRefresh -= dt;

#ifndef _RELEASE
	//Verify entity integrity
	InteractiveEntityDebugMap::iterator mapIter = m_debugMap.begin();
	InteractiveEntityDebugMap::iterator mapEnd = m_debugMap.end();
	while(mapIter != mapEnd)
	{
		if(!gEnv->pEntitySystem->GetEntity(mapIter->first))
		{
			CryLog("[ERROR] InteractiveEntityMonitor. About to crash. Registered entity no longer exists: '%s'. Tell Gary (Really this time).", mapIter->second.c_str());
			DesignerWarning(false, "[ERROR] InteractiveEntityMonitor. About to crash. Registered entity no longer exists: '%s'. Tell Gary (Really this time).", mapIter->second.c_str());
		}

		++mapIter;
	}
#endif //_RELEASE

	IEntitySystem* pEntitySys = gEnv->pEntitySystem;
	const Vec3& playerPos = GetOwnerPlayer()->GetEntity()->GetWorldTM().GetColumn3();
	if(m_bEnabled && (m_timeUntilRefresh < 0.f || playerPos.GetSquaredDistance2D(m_playerPrevPos) > g_pGameCVars->g_highlightingMovementDistanceToUpdateSquared))
	{
		for(InteractiveEntityList::iterator it = m_interactiveEntityList.begin(); it!=m_interactiveEntityList.end(); )
		{
			const EntityId entityId = it->first;
			IEntity* pEntity = pEntitySys->GetEntity(entityId);
			if(!pEntity)
			{
				it=m_interactiveEntityList.erase(it);
				continue;
			}

			if (IEntityRenderProxy* pRenderProxy = static_cast<IEntityRenderProxy *>(pEntity->GetProxy(ENTITY_PROXY_RENDER)))
			{
				const Vec3& entityPos = pEntity->GetWorldTM().GetColumn3();
				const float distSq = entityPos.GetSquaredDistance2D(playerPos);

				const bool withinHighlightDistance = distSq <= g_pGameCVars->g_highlightingMaxDistanceToHighlightSquared;
				if( withinHighlightDistance )
				{
					// Apply intensity fade over outer half distance
					float alpha = distSq * 2.0f - g_pGameCVars->g_highlightingMaxDistanceToHighlightSquared;
					alpha *= __fres(g_pGameCVars->g_highlightingMaxDistanceToHighlightSquared);
					alpha = 1.0f - clamp(alpha, 0.0f, 1.0f);

					if( (it->second & EIES_ShootToInteract) == 0 )
					{
						pRenderProxy->SetHUDSilhouettesParams(m_silhouetteInteractColor.r*alpha, m_silhouetteInteractColor.g*alpha, m_silhouetteInteractColor.b*alpha, m_silhouetteInteractColor.a*alpha);
					}
					else
					{
						pRenderProxy->SetHUDSilhouettesParams(m_silhouetteShootColor.r*alpha, m_silhouetteShootColor.g*alpha, m_silhouetteShootColor.b*alpha, m_silhouetteShootColor.a*alpha);
					}
					it->second |= EIES_Highlighted;
				}
				else if( it->second & EIES_Highlighted )
				{
					pRenderProxy->SetHUDSilhouettesParams(0.f, 0.f, 0.f, 0.f);
					it->second &= ~EIES_Highlighted;
				}
			}

			++it;
		}

		m_playerPrevPos = playerPos;
		m_timeUntilRefresh = g_pGameCVars->g_highlightingTimeBetweenForcedRefresh;
	}
}
示例#24
0
bool CXInputDevice::SetVibration(USHORT leftMotor, USHORT rightMotor, float timing, EFFEffectId effectId)
{
	//if(g_bConnected[m_deviceNo])
	if (m_connected)
	{
		USHORT desiredVibrationLeft = 0;
		USHORT desiredVibrationRight = 0;

		if (effectId == eFF_Rumble_Basic)
		{
			const float now = gEnv->pTimer->GetFrameStartTime().GetSeconds();

			if (m_fVibrationTimer > 0.0f)
			{
				const float oldRumbleRatio = (float)__fsel(-timing, 1.0f, min(1.0f, (fabsf(m_fVibrationTimer - now) * (float)__fres((timing + FLT_EPSILON)))));

				//Store only 'basic', without frame part
				m_basicLeftMotorRumble = max(leftMotor, (USHORT)(m_basicLeftMotorRumble * oldRumbleRatio));
				m_basicRightMotorRumble = max(rightMotor, (USHORT)(m_basicRightMotorRumble * oldRumbleRatio));

				const float newLeftMotor = GetClampedLeftMotorAccumulatedVibration() * oldRumbleRatio;
				const float newRightMotor = GetClampedRightMotorAccumulatedVibration() * oldRumbleRatio;
				desiredVibrationLeft = max(leftMotor, (USHORT)newLeftMotor);
				desiredVibrationRight = max(rightMotor, (USHORT)newRightMotor);
			}
			else
			{
				m_basicLeftMotorRumble = leftMotor;
				m_basicRightMotorRumble = rightMotor;		

				desiredVibrationLeft = max(leftMotor, (USHORT)GetClampedLeftMotorAccumulatedVibration() );
				desiredVibrationRight = max(rightMotor, (USHORT)GetClampedRightMotorAccumulatedVibration());
			}

			m_fVibrationTimer = (float)__fsel(-timing, 0.0f, now + timing);
		}
		else if (effectId == eFF_Rumble_Frame)
		{
			m_frameLeftMotorRumble = leftMotor;
			m_frameRightMotorRumble = rightMotor;

			desiredVibrationLeft = (USHORT)GetClampedLeftMotorAccumulatedVibration();
			desiredVibrationRight = (USHORT)GetClampedRightMotorAccumulatedVibration();
		}

		if(	m_currentVibrationSettings.wLeftMotorSpeed != desiredVibrationLeft ||
				m_currentVibrationSettings.wRightMotorSpeed != desiredVibrationRight  )
		{
			XINPUT_VIBRATION vibration;
			ZeroMemory( &vibration, sizeof(XINPUT_VIBRATION) );
			vibration.wLeftMotorSpeed = desiredVibrationLeft;
			vibration.wRightMotorSpeed = desiredVibrationRight;
			DWORD error = XInputSetState( m_deviceNo, &vibration );
			if(error == ERROR_SUCCESS)
			{
				m_currentVibrationSettings.wLeftMotorSpeed = desiredVibrationLeft;
				m_currentVibrationSettings.wRightMotorSpeed = desiredVibrationRight;
			}
		}

		return true;
	}
	return false;
}
示例#25
0
void CSmokeManager::UpdateSmokeInstance(SSmokeInstance& smokeInstance, float dt)
{
    IEntity * pGrenade = gEnv->pEntitySystem->GetEntity(smokeInstance.grenadeId);

    CullOtherSmokeEffectsInProximityWhenGrenadeHasLanded(smokeInstance,pGrenade);

    if(pGrenade)
        {
            //Update the radius of the smoke according to the speed of movement,
            //	it should reduce to nothing when moving fast enough, and should increase
            //	when the grenade is stationary
            Vec3 vNewPosition		= pGrenade->GetPos();

            Vec3 vPositionDiff	= vNewPosition - smokeInstance.vPositon;

            const float fDistanceTravelled = vPositionDiff.len();

            const float fSpeed = fDistanceTravelled * __fres(dt);

            const float fNewRadius = smokeInstance.fCurrentRadius + (float)__fsel( smokeInstance.fTimer-kInitialDelay, ((kSmokeRadiusIncrease - fSpeed) * dt), 0.0f);

            smokeInstance.fCurrentRadius = clamp(fNewRadius, 0.0f, kMaxSmokeRadius);

            // If grenade on ground, then override its timer to be maximum of kMaxPhysicsSleepTime
            if((smokeInstance.state == eSIS_Active_PhysicsAsleep) && (smokeInstance.fTimer < kInitialDelay-kMaxPhysicsSleepTime))
                {
                    smokeInstance.fTimer = kInitialDelay-kMaxPhysicsSleepTime;
                }

            const float previousTimer = smokeInstance.fTimer;
            smokeInstance.fTimer = smokeInstance.fTimer + dt;

            if(previousTimer < kInitialDelay && smokeInstance.fTimer >= kInitialDelay)
                {
                    // Spawn explosion particle effect
                    if (m_pExplosionParticleEffect)
                        {
                            m_pExplosionParticleEffect->Spawn(false,IParticleEffect::ParticleLoc(vNewPosition));
                        }

                    // Spawn smoke particle effect
                    // Find a free slot on the grenade
                    SEntitySlotInfo dummySlotInfo;
                    int i=0;
                    while (pGrenade->GetSlotInfo(i, dummySlotInfo))
                        {
                            i++;
                        }
                    if (m_pOutsideSmokeParticleEffect)
                        {
                            pGrenade->LoadParticleEmitter(i, m_pOutsideSmokeParticleEffect);

                            IParticleEmitter* pEmitter = pGrenade->GetParticleEmitter(i);
                            if(pEmitter)
                                {
                                    SpawnParams spawnParams;
                                    pEmitter->GetSpawnParams(spawnParams);
                                    pEmitter->SetSpawnParams(spawnParams);
                                }
                        }
                }

            //Update the smoke's position
            smokeInstance.vPositon = vNewPosition;

            if (smokeInstance.pObstructObject)
                {
                    pe_params_pos pos;
                    pos.scale = clamp(smokeInstance.fCurrentRadius * __fres(kMaxSmokeRadius), 0.1f, 1.0f);
                    pos.pos = vNewPosition;
                    smokeInstance.pObstructObject->SetParams(&pos);
                }
        }
    else
        {
            //The grenade entity has been deleted, so smoke has stopped being produced
            if(smokeInstance.fTimer > kSmokeEmitEndTime)
                {
                    //The smoke has cleared, delete the SmokeInstance
                    smokeInstance.state = eSIS_ForDeletion;
                }
            else
                {
                    //Count down the remaining life, and reduce the radius
                    smokeInstance.fTimer					+= dt;
                    smokeInstance.fCurrentRadius  = max(smokeInstance.fCurrentRadius - (dt * kMaxSmokeRadius / kSmokeLingerTime), 0.0f);

                    if (smokeInstance.pObstructObject)
                        {
                            pe_params_pos pos;
                            pos.scale = clamp(smokeInstance.fCurrentRadius * __fres(kMaxSmokeRadius), 0.1f, 1.0f);

                            smokeInstance.pObstructObject->SetParams(&pos);
                        }
                }
        }
}
void CWeapon::NetUpdateFireMode(SEntityUpdateContext& ctx)
{
    // CGunTurret and CVehicleWeapon overide NetAllowUpdate to perform their own checks.
    if(NetAllowUpdate(true))
    {
        m_netNextShot -= ctx.fFrameTime;

        if(IsReloading())
            return;	// reloading, bail

        if((!m_isFiringStarted) && (m_isFiring || m_shootCounter > 0))
        {
            m_isFiringStarted = true;
            m_netNextShot = 0.f;
            NetStartFire();
            EnableUpdate(true, eIUS_FireMode);
        }

        if(m_fm)
        {
            if(m_shootCounter > 0 && m_netNextShot <= 0.0f)
            {
                // Aside from the prediction handle, needed for the server, NetShoot/Ex parameters
                // are no longer used, these will need removing when the client->server RMI's are tided up
                m_fm->NetShoot(Vec3(0.f, 0.f, 0.f), 0);
                m_shootCounter--;

                //if fireRate == 0.0f, set m_netNextShot to 0.0f, otherwise increment by 60.f / fireRate.
                //	fres used to avoid microcoded instructions, fsel to avoid branching - Rich S
                const float fRawFireRate		= m_fm->GetFireRate();
                const float fFireRateSelect = -fabsf(fRawFireRate);
                const float fFireRateForDiv = (float)__fsel(fFireRateSelect, 1.0f, fRawFireRate);
                const float fNextShot				= (float)__fsel(fFireRateSelect, 0.0f, m_netNextShot + (60.f * __fres(fFireRateForDiv)));
                m_netNextShot = fNextShot;
            }
        }

        if(m_isFiringStarted && !m_isFiring && m_shootCounter <= 0)
        {
            m_isFiringStarted = false;
            NetStopFire();
            EnableUpdate(false, eIUS_FireMode);
        }

        // this needs to happen here, or NetStopFire interrupts the animation
        if(m_doMelee && m_melee)
        {
            m_melee->NetAttack();
            m_doMelee= false;
        }
    }

}
void CMountedGunController::Update(EntityId mountedGunID, float frameTime)
{
    CRY_ASSERT_MESSAGE(m_pControlledPlayer, "Controlled player not initialized");

    CItem* pMountedGun = static_cast<CItem*>(gEnv->pGame->GetIGameFramework()->GetIItemSystem()->GetItem(mountedGunID));

    bool canUpdateMountedGun = (pMountedGun != NULL) && (pMountedGun->GetStats().mounted);

    if (canUpdateMountedGun)
        {
            IMovementController * pMovementController = m_pControlledPlayer->GetMovementController();
            assert(pMovementController);

            SMovementState info;
            pMovementController->GetMovementState(info);

            IEntity* pMountedGunEntity = pMountedGun->GetEntity();
            const Matrix34& lastMountedGunWorldTM = pMountedGunEntity->GetWorldTM();

            Vec3 desiredAimDirection = info.aimDirection.GetNormalized();

            // AI can switch directions too fast, prevent snapping
            if(!m_pControlledPlayer->IsPlayer())
                {
                    const Vec3 currentDir = lastMountedGunWorldTM.GetColumn1();
                    const float dot = clamp(currentDir.Dot(desiredAimDirection), -1.0f, 1.0f);
                    const float reqAngle = cry_acosf(dot);
                    const float maxRotSpeed = 2.0f;
                    const float maxAngle = frameTime * maxRotSpeed;
                    if(fabs(reqAngle) > maxAngle)
                        {
                            const Vec3 axis = currentDir.Cross(desiredAimDirection);
                            if(axis.GetLengthSquared() > 0.001f) // current dir and new dir are enough different
                                {
                                    desiredAimDirection = currentDir.GetRotated(axis.GetNormalized(),sgn(reqAngle)*maxAngle);
                                }
                        }
                }

            bool isUserClient = m_pControlledPlayer->IsClient();

            IEntity* pMountedGunParentEntity = pMountedGunEntity->GetParent();
            IVehicle *pVehicle = NULL;
            if(pMountedGunParentEntity && m_pControlledPlayer)
                pVehicle = m_pControlledPlayer->GetLinkedVehicle();

            CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem();

            //For client update always, for others only when there is notable change
            if (!pVehicle && (isUserClient || (!desiredAimDirection.IsEquivalent(lastMountedGunWorldTM.GetColumn1(), 0.003f))))
                {
                    Quat rotation = Quat::CreateRotationVDir(desiredAimDirection, 0.0f);
                    pMountedGunEntity->SetRotation(rotation);

                    if (isUserClient && pRecordingSystem)
                        {
                            // Only record the gun position if you're using the gun.
                            pRecordingSystem->OnMountedGunRotate(pMountedGunEntity, rotation);
                        }
                }

            const Vec3 vInitialAimDirection = GetMountDirection(pMountedGun, pMountedGunParentEntity);
            assert( vInitialAimDirection.IsUnit() );

            //Adjust gunner position and animations
            UpdateGunnerLocation(pMountedGun, pMountedGunParentEntity, vInitialAimDirection);

            const float aimrad = Ang3::CreateRadZ(Vec2(vInitialAimDirection),Vec2(-desiredAimDirection));
            const float pitchLimit = sin_tpl(DEG2RAD(30.0f));
            const float animHeight = fabs_tpl(clamp(desiredAimDirection.z * (float)__fres(pitchLimit), -1.0f, 1.0f));

            const float aimUp = (float)__fsel(-desiredAimDirection.z, 0.0f, animHeight);
            const float aimDown = (float)__fsel(desiredAimDirection.z, 0.0f, animHeight);

            if (pRecordingSystem)
                {
                    pRecordingSystem->OnMountedGunUpdate(m_pControlledPlayer, aimrad, aimUp, aimDown);
                }

            if(!m_pControlledPlayer->IsThirdPerson())
                {
                    UpdateFirstPersonAnimations(pMountedGun, desiredAimDirection);
                }

            if(m_pMovementAction)
                {
                    const float aimUpParam = aimUp;
                    const float aimDownParam = aimDown;
                    const float aimMovementParam = CalculateAnimationTime(aimrad);

                    m_pMovementAction->SetParam(MountedGunCRCs.aimUpParam, aimUpParam);
                    m_pMovementAction->SetParam(MountedGunCRCs.aimDownParam, aimDownParam);
                    m_pMovementAction->SetParam(MountedGunCRCs.aimMovementParam, aimMovementParam);
                }

            UpdateIKMounted(pMountedGun);
        }
}
示例#28
0
void CPlayerStateGround::OnPrePhysicsUpdate( CPlayer& player, const SActorFrameMovementParams &movement, float frameTime, const bool isHeavyWeapon, const bool isPlayer )
{
	const Matrix34A baseMtx = Matrix34A(player.GetBaseQuat());
	Matrix34A baseMtxZ(baseMtx * Matrix33::CreateScale(Vec3Constants<float>::fVec3_OneZ));
	baseMtxZ.SetTranslation(Vec3Constants<float>::fVec3_Zero);

	const CAutoAimManager& autoAimManager = g_pGame->GetAutoAimManager();
	const EntityId closeCombatTargetId = autoAimManager.GetCloseCombatSnapTarget();
	const IActor* pCloseCombatTarget = isPlayer && closeCombatTargetId && player.IsClient() ? g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(closeCombatTargetId) : NULL;

	if (pCloseCombatTarget)
	{
		ProcessAlignToTarget(autoAimManager, player, pCloseCombatTarget);
	}
	else
	{
		// This is to restore inertia if the ProcessAlignToTarget set it previously.
		if( m_inertiaIsZero )
		{
			CPlayerStateUtil::RestorePlayerPhysics( player );

			m_inertiaIsZero = false;
		}

		//process movement
		const bool isRemote = isPlayer && !player.IsClient();

		Vec3 move(ZERO);
		CPlayerStateUtil::CalculateGroundOrJumpMovement( player, movement, isHeavyWeapon, move );
		player.GetMoveRequest().type = eCMT_Normal;






		//apply movement
		Vec3 desiredVel(ZERO);
		Vec3 entityPos = player.GetEntity()->GetWorldPos();
		Vec3 entityRight(player.GetBaseQuat().GetColumn0());

		hwvec3 xmDesiredVel = HWV3Zero();

		hwmtx33 xmBaseMtxZ;
		HWMtx33LoadAligned(xmBaseMtxZ, baseMtxZ);
		hwmtx33 xmBaseMtxZOpt = HWMtx33GetOptimized(xmBaseMtxZ);

		hwvec3 xmMove					= HWVLoadVecUnaligned(&move);	
		simdf fGroundNormalZ;

#ifdef STATE_DEBUG
		bool debugJumping = (g_pGameCVars->pl_debug_jumping != 0);
#endif

		const SPlayerStats& stats = *player.GetActorStats();

		{
			xmDesiredVel = xmMove;

			Vec3 groundNormal = player.GetActorPhysics().groundNormal;

			if(!gEnv->bMultiplayer)
			{
				if (player.IsAIControlled())
					fGroundNormalZ = SIMDFLoadFloat(square(groundNormal.z));
				else
					fGroundNormalZ = SIMDFLoadFloat(groundNormal.z);
			}
			else
			{
				//If the hill steepness is greater than our minimum threshold
				if(groundNormal.z > 1.f - cosf(g_pGameCVars->pl_movement.mp_slope_speed_multiplier_minHill))
				{
					//Check if we are trying to move up or downhill
					groundNormal.z = 0.f;
					groundNormal.Normalize();

					Vec3 moveDir = move;
					moveDir.z = 0.f;
					moveDir.Normalize();

					float normalDotMove = groundNormal.Dot(moveDir);
					//Apply speed multiplier based on moving up/down hill and hill steepness
					float multiplier = normalDotMove < 0.f ? g_pGameCVars->pl_movement.mp_slope_speed_multiplier_uphill : g_pGameCVars->pl_movement.mp_slope_speed_multiplier_downhill;
					fGroundNormalZ = SIMDFLoadFloat(1.f - (1.f - player.GetActorPhysics().groundNormal.z) * multiplier);
				}
				else
				{
					fGroundNormalZ = SIMDFLoadFloat(1.0f);
				}
			}

			const float depthHi = g_pGameCVars->cl_shallowWaterDepthHi;
			const float depthLo = g_pGameCVars->cl_shallowWaterDepthLo;
			const float relativeBottomDepth = player.m_playerStateSwim_WaterTestProxy.GetRelativeBottomDepth();

			if( relativeBottomDepth > depthLo )
			{ // Shallow water speed slowdown
				float shallowWaterMultiplier = 1.0f;

				shallowWaterMultiplier = isPlayer
					? g_pGameCVars->cl_shallowWaterSpeedMulPlayer
					: g_pGameCVars->cl_shallowWaterSpeedMulAI;

				shallowWaterMultiplier = max(shallowWaterMultiplier, 0.1f);
				assert(shallowWaterMultiplier <= 1.0f);


				float shallowWaterDepthSpan = (depthHi - depthLo);
				shallowWaterDepthSpan = max(0.1f, shallowWaterDepthSpan);

				float slowdownFraction = (relativeBottomDepth - depthLo) / shallowWaterDepthSpan;
				slowdownFraction = clamp_tpl(slowdownFraction, 0.0f, 1.0f);
				shallowWaterMultiplier = LERP(1.0f, shallowWaterMultiplier, slowdownFraction);

				//avoid branch if m_stats.relativeBottomDepth <= 0.0f;
				shallowWaterMultiplier = (float)__fsel(-relativeBottomDepth, 1.0f, shallowWaterMultiplier);

				simdf vfShallowWaterMultiplier = SIMDFLoadFloat(shallowWaterMultiplier);

				xmDesiredVel = HWVMultiplySIMDF(xmDesiredVel, vfShallowWaterMultiplier);
			}
		}





		// Slow down on sloped terrain, simply proportional to the slope. 
		xmDesiredVel = HWVMultiplySIMDF(xmDesiredVel, fGroundNormalZ);

		//be sure desired velocity is flat to the ground
		hwvec3 vDesiredVelVert = HWMtx33RotateVecOpt(xmBaseMtxZOpt, xmDesiredVel);

		xmDesiredVel = HWVSub(xmDesiredVel, vDesiredVelVert);

		HWVSaveVecUnaligned(&desiredVel, xmDesiredVel);

		if (isPlayer)
		{
			Vec3 modifiedSlopeNormal = player.GetActorPhysics().groundNormal;
			float h = Vec2(modifiedSlopeNormal.x, modifiedSlopeNormal.y).GetLength(); // TODO: OPT: sqrt(x*x+y*y)
			float v = modifiedSlopeNormal.z;
			float slopeAngleCur = RAD2DEG(atan2_tpl(h, v));

			const float divisorH = (float)__fsel(-h, 1.0f, h);
			const float divisorV = (float)__fsel(-v, 1.0f, v);

			const float invV = __fres(divisorV);
			const float invH = __fres(divisorH);

			const float slopeAngleHor = 10.0f;
			const float slopeAngleVer = 50.0f;
			float slopeAngleFraction = clamp_tpl((slopeAngleCur - slopeAngleHor) * __fres(slopeAngleVer - slopeAngleHor), 0.0f, 1.0f);

			slopeAngleFraction = slopeAngleFraction * slopeAngleFraction * slopeAngleFraction;

			float slopeAngleMod = LERP(0.0f, 90.0f, slopeAngleFraction);

			float s, c;

			sincos_tpl(DEG2RAD(slopeAngleMod), &s, &c);

			const float hMultiplier = (float)__fsel(-h, 1.0f, s * invH);
			const float vMultiplier = (float)__fsel(-v, 1.0f, c * invV);

			modifiedSlopeNormal.x *= hMultiplier;
			modifiedSlopeNormal.y *= hMultiplier;
			modifiedSlopeNormal.z *= vMultiplier;

			//Normalize the slope normal if possible
			const float fSlopeNormalLength = modifiedSlopeNormal.len();
			const float fSlopeNormalLengthSafe = (float)__fsel(fSlopeNormalLength - 0.000001f, fSlopeNormalLength, 1.0f);
			modifiedSlopeNormal = modifiedSlopeNormal * __fres(fSlopeNormalLengthSafe);

			float alignment = min(modifiedSlopeNormal * desiredVel, 0.0f);

			// Also affect air control (but not as much), to prevent jumping up against steep slopes.

			alignment *= (float)__fsel(-fabsf(stats.onGround), LERP(0.7f, 1.0f, 1.0f - clamp_tpl(modifiedSlopeNormal.z * 100.0f, 0.0f, 1.0f)), 1.0f);

			modifiedSlopeNormal.z = modifiedSlopeNormal.z;

			desiredVel -= modifiedSlopeNormal * alignment;


#ifdef STATE_DEBUG
			if (debugJumping)
			{
				player.DebugGraph_AddValue("GroundSlope", slopeAngleCur);
				player.DebugGraph_AddValue("GroundSlopeMod", slopeAngleMod);
			}
#endif
		}





		Vec3 newVelocity = desiredVel;

		const float fNewSpeed = newVelocity.len();

		const float fVelocityMultiplier = (float)__fsel(fNewSpeed - 22.0f, __fres(fNewSpeed+FLT_EPSILON) * 22.0f, 1.0f);

		// TODO: Maybe we should tell physics about this new velocity ? Or maybe SPlayerStats::velocity ? (stephenn).
		player.GetMoveRequest().velocity = newVelocity * (stats.flashBangStunMult * fVelocityMultiplier);

#ifdef STATE_DEBUG
		if(g_pGameCVars->pl_debug_movement > 0)
		{
			const char* filter = g_pGameCVars->pl_debug_filter->GetString();
			const char* name = player.GetEntity()->GetName();
			if ((strcmp(filter, "0") == 0) || (strcmp(filter, name) == 0))
			{
				float white[] = {1.0f,1.0f,1.0f,1.0f};
				gEnv->pRenderer->Draw2dLabel(20, 450, 2.0f, white, false, "Speed: %.3f m/s", player.GetMoveRequest().velocity.len());

				if(g_pGameCVars->pl_debug_movement > 1)
				{
					gEnv->pRenderer->Draw2dLabel(35, 470, 1.8f, white, false, "Stance Speed: %.3f m/s - (%sSprinting)", player.GetStanceMaxSpeed(player.GetStance()), player.IsSprinting() ? "" : "Not ");
				}
			}
		}
#endif


























	}

	if( isPlayer )
	{
		CheckForVaultTrigger(player, frameTime);
	}
}
示例#29
0
bool CSmokeManager::IsPointInSmoke(const Vec3& vPos, float& outInsideFactor) const
{
    const int kNumActiveSmokeInstances = m_numActiveSmokeInstances;

    PrefetchLine(m_smokeInstances, 0);
    PrefetchLine(m_smokeInstances, 128);

    outInsideFactor = 0.0f;

    for(int i = 0; i < kNumActiveSmokeInstances; i++)
        {
            const SSmokeInstance& smokeInstance = m_smokeInstances[i];

            PrefetchLine(&smokeInstance, 128);

            const float fDistanceSq = Distance::Point_PointSq(vPos, smokeInstance.vPositon);
            const float fCurrentRadiusSq = sqr(smokeInstance.fCurrentRadius);
            if(fDistanceSq < fCurrentRadiusSq)
                {
                    outInsideFactor = 1.0f - ((float)cry_sqrtf_fast(fDistanceSq) * (float)__fres(cry_sqrtf_fast(fCurrentRadiusSq)));
                    return true;
                }
        }

    return false;
}
void CRecoil::UpdateSpread(bool weaponFired, bool weaponFiring, float frameTime)
{
	const bool isFiring = m_singleShot ? weaponFired : weaponFiring;
	const float decay = isFiring ? m_spreadParams.decay : m_spreadParams.end_decay;
	const float frameDecay = (float)__fsel(-decay, 0.0f, ((m_spreadParams.max - m_spreadParams.min) * __fres(decay + FLT_EPSILON)) * frameTime);

	float newSpread = clamp(m_spread - frameDecay, m_spreadParams.min, (m_spreadParams.max * m_maxSpreadMultiplier));

	if(newSpread < m_spreadParams.max)
	{
		m_maxSpreadMultiplier = 1.f;
	}

	m_spread = newSpread;

	CRecoilDebugDraw::DebugSpread(GetSpread());
}