// Fill out your copyright notice in the Description page of Project Settings. #include "SurvivalUserSettings.h" #include "Engine/Engine.h" namespace { /** Arrondit sur le palier le plus proche, puis borne. */ float SnapToStep(float Value, float Min, float Max, float Step) { const float Snapped = Min + FMath::RoundToFloat((Value - Min) / Step) * Step; return FMath::Clamp(Snapped, Min, Max); } } USurvivalUserSettings::USurvivalUserSettings() { // Le constructeur tourne sur le CDO, avant toute lecture du .ini : ces // valeurs sont donc bien les defauts d'usine, ecrasees ensuite par le // fichier s'il existe. SetSurvivalGameplayToDefaults(); } USurvivalUserSettings* USurvivalUserSettings::Get() { return GEngine ? Cast(GEngine->GetGameUserSettings()) : nullptr; } void USurvivalUserSettings::SetSurvivalGameplayToDefaults() { LookSensitivity = 35.f; bSeparateVerticalSensitivity = false; LookSensitivityVertical = 35.f; bInvertLookY = false; FieldOfView = 90.f; CameraShakeScale = 100.f; bSprintToggle = false; bCrouchToggle = false; } void USurvivalUserSettings::SetToDefaults() { // Le "Reinitialiser" global du moteur doit aussi remettre NOS valeurs : // sans cette surcharge, l'onglet Jeu resterait seul inchange. Super::SetToDefaults(); SetSurvivalGameplayToDefaults(); } void USurvivalUserSettings::ApplySurvivalSettings() { OnSurvivalSettingsApplied.Broadcast(); } void USurvivalUserSettings::ApplyNonResolutionSettings() { Super::ApplyNonResolutionSettings(); // ApplySettings() passe forcement par ici : brancher la diffusion a ce // niveau garantit que nos reglages suivent, quel que soit le chemin. ApplySurvivalSettings(); } float USurvivalUserSettings::GetLookMultiplierX() const { using namespace SurvivalSettingsRange; const float Normalized = FMath::GetRangePct(SensitivityMin, SensitivityMax, LookSensitivity); return FMath::Lerp(LookMultiplierAtMin, LookMultiplierAtMax, Normalized); } float USurvivalUserSettings::GetLookMultiplierY() const { using namespace SurvivalSettingsRange; // Sans axe separe, le vertical suit l'horizontal : c'est ce que veulent // 95 % des joueurs, et deux curseurs desynchronises par inadvertance // donnent une visee bancale sans qu'on comprenne pourquoi. if (!bSeparateVerticalSensitivity) { return GetLookMultiplierX(); } const float Normalized = FMath::GetRangePct(SensitivityMin, SensitivityMax, LookSensitivityVertical); return FMath::Lerp(LookMultiplierAtMin, LookMultiplierAtMax, Normalized); } float USurvivalUserSettings::GetCameraShakeMultiplier() const { return FMath::Clamp(CameraShakeScale / 100.f, 0.f, 1.f); } void USurvivalUserSettings::SetLookSensitivity(float Value) { using namespace SurvivalSettingsRange; LookSensitivity = SnapToStep(Value, SensitivityMin, SensitivityMax, SensitivityStep); } void USurvivalUserSettings::SetSeparateVerticalSensitivity(bool bValue) { // En repassant sur "non separe" on recale le vertical sur l'horizontal : // sinon la valeur oubliee ressortirait telle quelle a la reactivation. if (!bValue) { LookSensitivityVertical = LookSensitivity; } bSeparateVerticalSensitivity = bValue; } void USurvivalUserSettings::SetLookSensitivityVertical(float Value) { using namespace SurvivalSettingsRange; LookSensitivityVertical = SnapToStep(Value, SensitivityMin, SensitivityMax, SensitivityStep); } void USurvivalUserSettings::SetInvertLookY(bool bValue) { bInvertLookY = bValue; } void USurvivalUserSettings::SetFieldOfView(float Value) { using namespace SurvivalSettingsRange; FieldOfView = SnapToStep(Value, FieldOfViewMin, FieldOfViewMax, FieldOfViewStep); } void USurvivalUserSettings::SetCameraShakeScale(float Value) { using namespace SurvivalSettingsRange; CameraShakeScale = SnapToStep(Value, CameraShakeMin, CameraShakeMax, CameraShakeStep); } void USurvivalUserSettings::SetSprintToggle(bool bValue) { bSprintToggle = bValue; } void USurvivalUserSettings::SetCrouchToggle(bool bValue) { bCrouchToggle = bValue; }