using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CinematicCamera.Patches;
using GameNetcodeStuff;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("CinematicCamera")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CinematicCamera")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a1037d4d-b8aa-4e06-a09e-fdfccf82e77d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CinematicCamera
{
[BepInPlugin("sysfab.cinematiccamera", "Cinematic Camera", "1.0.0")]
public class CinematicCameraBase : BaseUnityPlugin
{
private const string modGUID = "sysfab.cinematiccamera";
private const string modName = "Cinematic Camera";
private const string modVersion = "1.0.0";
private readonly Harmony harmony = new Harmony("sysfab.cinematiccamera");
public static CinematicCameraBase Instance;
internal ManualLogSource Log;
internal static ConfigEntry<bool> PositionEffects;
internal static ConfigEntry<bool> RotationEffects;
internal static ConfigEntry<bool> HealthCondition;
internal static ConfigEntry<int> HealthConditionTriggerLimit;
internal static ConfigEntry<bool> HealthConditionSmoothing;
internal static ConfigEntry<bool> EnableMouseFactor;
internal static ConfigEntry<float> MouseFactorSmoothness;
internal static ConfigEntry<float> MouseFactorXMultiplier;
internal static ConfigEntry<float> MouseFactorYMultiplier;
internal static ConfigEntry<float> MouseFactorZMultiplier;
internal static ConfigEntry<bool> EnableFallingFactor;
internal static ConfigEntry<float> FallingFactorSmoothness;
internal static ConfigEntry<float> FallingFactorMultiplier;
internal static ConfigEntry<bool> EnableMoveFactor;
internal static ConfigEntry<float> MoveFactorSmoothness;
internal static ConfigEntry<float> MoveFactorStrafeMultiplier;
internal static ConfigEntry<float> MoveFactorForwardMultiplier;
internal static ConfigEntry<float> MoveFactorBackwardMultiplier;
internal static ConfigEntry<bool> EnableFallShake;
internal static ConfigEntry<float> FallShakeMultiplier;
internal static ConfigEntry<float> FallShakeMinVelocity;
internal static ConfigEntry<float> FallShakeMaxVelocity;
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
Log = Logger.CreateLogSource("sysfab.cinematiccamera");
Log.LogInfo((object)"Loading config entries...");
PositionEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Position Effects", true, "Mod will change camera's position if enabled");
RotationEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Rotation Effects", true, "Mod will change camera's rotation if enabled");
HealthCondition = ((BaseUnityPlugin)this).Config.Bind<bool>("Health Condition", "Enabled", false, "Mod will work if health condition (or others) is met");
HealthConditionTriggerLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Health Condition", "Trigger limit", 20, "If health is <= trigger value then mod will start to work");
HealthConditionSmoothing = ((BaseUnityPlugin)this).Config.Bind<bool>("Health Condition", "Smoothing", false, "If health is close to trigger value then effect will be small");
EnableMouseFactor = ((BaseUnityPlugin)this).Config.Bind<bool>("Mouse Factor", "Enabled", true, "Moving mouse will affect camera");
MouseFactorSmoothness = ((BaseUnityPlugin)this).Config.Bind<float>("Mouse Factor", "Smoothness", 1f, "Smoothness of mouse factor, Default: 1. Values from 0.5 to 2 recommended");
MouseFactorXMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Mouse Factor", "X Multiplier", 1f, "X axis multiplier, Default: 1");
MouseFactorYMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Mouse Factor", "Y Multiplier", 1f, "Y axis multiplier, Default: 1");
MouseFactorZMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Mouse Factor", "Z Multiplier", 1f, "Z axis multiplier, Default: 1");
EnableFallingFactor = ((BaseUnityPlugin)this).Config.Bind<bool>("Falling Factor", "Enabled", true, "Falling will affect camera");
FallingFactorSmoothness = ((BaseUnityPlugin)this).Config.Bind<float>("Falling Factor", "Smoothness", 1f, "Smoothness of falling factor, Default: 1. Values from 0.5 to 2 recommended");
FallingFactorMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Falling Factor", "Multiplier", 1f, "Falling effect multiplier, Default: 1");
EnableMoveFactor = ((BaseUnityPlugin)this).Config.Bind<bool>("Move Factor", "Enabled", true, "Moving will affect camera");
MoveFactorSmoothness = ((BaseUnityPlugin)this).Config.Bind<float>("Move Factor", "Smoothness", 1f, "Smoothness of move factor, Default: 1. Values from 0.5 to 2 recommended");
MoveFactorStrafeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Move Factor", "Strafe Multiplier", 1f, "Strafe multiplier, Default: 1");
MoveFactorForwardMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Move Factor", "Forward Multiplier", 1f, "Forward multiplier, Default: 1");
MoveFactorBackwardMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Move Factor", "Backward Multiplier", 1f, "Backward multiplier, Default: 1");
EnableFallShake = ((BaseUnityPlugin)this).Config.Bind<bool>("Fall Shake", "Enabled", true, "Falling will shake camera");
FallShakeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Fall Shake", "Multiplier", 1f, "Falling shake multiplier, Default: 1");
FallShakeMinVelocity = ((BaseUnityPlugin)this).Config.Bind<float>("Fall Shake", "Min Velocity", 15f, "Minimum velocity to shake camera, Default: 15");
FallShakeMaxVelocity = ((BaseUnityPlugin)this).Config.Bind<float>("Fall Shake", "Max Velocity", 500f, "Maximum velocity to shake camera, Default: 500");
Log.LogInfo((object)"Config entries loaded!");
Log.LogInfo((object)"Cinematic Camera is loaded!");
harmony.PatchAll(typeof(CinematicCameraBase));
harmony.PatchAll(typeof(CameraPatch));
}
}
}
namespace CinematicCamera.Patches
{
[HarmonyPatch(typeof(PlayerControllerB))]
internal class CameraPatch
{
internal static ConfigEntry<bool> PositionEffects = CinematicCameraBase.PositionEffects;
internal static ConfigEntry<bool> RotationEffects = CinematicCameraBase.RotationEffects;
internal static ConfigEntry<bool> HealthCondition = CinematicCameraBase.HealthCondition;
internal static ConfigEntry<int> HealthConditionTriggerLimit = CinematicCameraBase.HealthConditionTriggerLimit;
internal static ConfigEntry<bool> HealthConditionSmoothing = CinematicCameraBase.HealthConditionSmoothing;
internal static ConfigEntry<bool> EnableMouseFactor = CinematicCameraBase.EnableMouseFactor;
internal static ConfigEntry<float> MouseFactorSmoothness = CinematicCameraBase.MouseFactorSmoothness;
internal static ConfigEntry<float> MouseFactorXMultiplier = CinematicCameraBase.MouseFactorXMultiplier;
internal static ConfigEntry<float> MouseFactorYMultiplier = CinematicCameraBase.MouseFactorYMultiplier;
internal static ConfigEntry<float> MouseFactorZMultiplier = CinematicCameraBase.MouseFactorZMultiplier;
internal static ConfigEntry<bool> EnableFallingFactor = CinematicCameraBase.EnableFallingFactor;
internal static ConfigEntry<float> FallingFactorSmoothness = CinematicCameraBase.FallingFactorSmoothness;
internal static ConfigEntry<float> FallingFactorMultiplier = CinematicCameraBase.FallingFactorMultiplier;
internal static ConfigEntry<bool> EnableMoveFactor = CinematicCameraBase.EnableMoveFactor;
internal static ConfigEntry<float> MoveFactorSmoothness = CinematicCameraBase.MoveFactorSmoothness;
internal static ConfigEntry<float> MoveFactorStrafeMultiplier = CinematicCameraBase.MoveFactorStrafeMultiplier;
internal static ConfigEntry<float> MoveFactorForwardMultiplier = CinematicCameraBase.MoveFactorForwardMultiplier;
internal static ConfigEntry<float> MoveFactorBackwardMultiplier = CinematicCameraBase.MoveFactorBackwardMultiplier;
internal static ConfigEntry<bool> EnableFallShake = CinematicCameraBase.EnableFallShake;
internal static ConfigEntry<float> FallShakeMultiplier = CinematicCameraBase.FallShakeMultiplier;
internal static ConfigEntry<float> FallShakeMinVelocity = CinematicCameraBase.FallShakeMinVelocity;
internal static ConfigEntry<float> FallShakeMaxVelocity = CinematicCameraBase.FallShakeMaxVelocity;
private static PlayerControllerB Instance;
private static Vector3 SavedCameraPosition = Vector3.zero;
private static Quaternion SavedCameraRotation = Quaternion.identity;
private static int inVehicleTicks = 0;
private static bool isInVehicle = false;
private static Vector3 prevLookVector = Vector3.zero;
private static Vector3 lastLookVector = Vector3.zero;
private static Vector3 prevVelocity = Vector3.zero;
private static Vector3 lastVelocity = Vector3.zero;
private static Vector2 prevMove = Vector2.zero;
private static Vector2 lastMove = Vector2.zero;
private static float fallShakeAmount = 0f;
private static float fallShakeSmooth = 0f;
private static Vector3 smoothLookVector = Vector3.zero;
private static Vector3 smoothVelocity = Vector3.zero;
private static Vector2 smoothMove = Vector2.zero;
private static float Ticks = 0f;
internal static CinematicCameraBase CinematicCamera => CinematicCameraBase.Instance;
internal static ManualLogSource Log => CinematicCamera.Log;
private static void SaveCameraState()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
SavedCameraPosition = ((Component)Instance.cameraContainerTransform).transform.position;
SavedCameraRotation = ((Component)Instance.cameraContainerTransform).transform.localRotation;
}
private static void RestoreCameraState()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
if (SavedCameraPosition == Vector3.zero && SavedCameraRotation == Quaternion.identity)
{
Log.LogWarning((object)"RestoreCameraState | Camera state is not saved yet. Skipping restoration.");
return;
}
if ((Object)(object)Instance == (Object)null)
{
Log.LogError((object)"RestoreCameraState | Instance is null!");
return;
}
if ((Object)(object)Instance.cameraContainerTransform == (Object)null)
{
Log.LogError((object)"RestoreCameraState | cameraContainerTransform is null!");
return;
}
if ((Object)(object)Instance.gameplayCamera == (Object)null)
{
Log.LogError((object)"RestoreCameraState | gameplayCamera is null!");
return;
}
if (PositionEffects != null && PositionEffects.Value)
{
((Component)Instance.cameraContainerTransform).transform.position = SavedCameraPosition;
}
if (RotationEffects != null && RotationEffects.Value)
{
((Component)Instance.cameraContainerTransform).transform.localRotation = SavedCameraRotation;
}
}
[HarmonyPatch(typeof(PlayerControllerB), "Awake")]
[HarmonyPrefix]
private static void Awake(ref PlayerControllerB __instance)
{
Instance = __instance;
Log.LogInfo((object)"CameraPatch Awake called");
((Renderer)GameObject.Find("Systems/Rendering/PlayerHUDHelmetModel/ScavengerHelmet").GetComponent<MeshRenderer>()).enabled = false;
}
[HarmonyPrefix]
[HarmonyPatch("Update")]
private static void Update(ref PlayerControllerB __instance)
{
if ((Object)(object)Instance == (Object)null)
{
Log.LogWarning((object)"Instance is null in Update");
Instance = __instance;
}
else
{
Ticks += Time.deltaTime;
RestoreCameraState();
}
}
[HarmonyPostfix]
[HarmonyPatch("LateUpdate")]
private static void LateUpdate(ref PlayerControllerB __instance, ref bool ___inTerminalMenu, ref QuickMenuManager ___quickMenuManager, ref bool ___isTypingChat, ref bool ___disableMoveInput, ref bool ___inSpecialInteractAnimation, ref bool ___isClimbingLadder, ref bool ___inShockingMinigame, ref bool ___inVehicleAnimation, ref int ___health)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_0260: Unknown result type (might be due to invalid IL or missing references)
//IL_0265: Unknown result type (might be due to invalid IL or missing references)
//IL_0234: Unknown result type (might be due to invalid IL or missing references)
//IL_0239: Unknown result type (might be due to invalid IL or missing references)
//IL_0254: Unknown result type (might be due to invalid IL or missing references)
//IL_0259: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
//IL_0205: Unknown result type (might be due to invalid IL or missing references)
//IL_020a: Unknown result type (might be due to invalid IL or missing references)
//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0402: Unknown result type (might be due to invalid IL or missing references)
//IL_041d: Unknown result type (might be due to invalid IL or missing references)
//IL_0422: Unknown result type (might be due to invalid IL or missing references)
//IL_0282: Unknown result type (might be due to invalid IL or missing references)
//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0317: Unknown result type (might be due to invalid IL or missing references)
//IL_0341: Unknown result type (might be due to invalid IL or missing references)
//IL_0346: Unknown result type (might be due to invalid IL or missing references)
//IL_049e: Unknown result type (might be due to invalid IL or missing references)
//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
SaveCameraState();
prevLookVector = lastLookVector;
MovementActions movement = __instance.playerActions.Movement;
lastLookVector = Vector2.op_Implicit(((MovementActions)(ref movement)).Look.ReadValue<Vector2>());
prevVelocity = lastVelocity;
lastVelocity = __instance.thisController.velocity;
prevMove = lastMove;
lastMove = IngamePlayerSettings.Instance.playerInput.actions.FindAction("Move", false).ReadValue<Vector2>();
if (___inVehicleAnimation)
{
inVehicleTicks = 10;
}
else
{
inVehicleTicks--;
}
if (inVehicleTicks > 0)
{
isInVehicle = true;
}
else
{
isInVehicle = false;
}
if (___inTerminalMenu | ___quickMenuManager.isMenuOpen | ___isTypingChat | ___disableMoveInput | ___inSpecialInteractAnimation | ___isClimbingLadder | ___inShockingMinigame | isInVehicle)
{
return;
}
Transform cameraContainerTransform = __instance.cameraContainerTransform;
if (EnableMouseFactor.Value)
{
if (MouseFactorSmoothness.Value > 0f)
{
smoothLookVector = Vector3.Lerp(smoothLookVector, lastLookVector, Time.deltaTime * 1.4f / MouseFactorSmoothness.Value);
}
else
{
smoothLookVector = lastLookVector;
}
cameraContainerTransform.localRotation *= Quaternion.Euler((0f - smoothLookVector.y) * 0.014f * MouseFactorXMultiplier.Value, smoothLookVector.x * 0.01f * MouseFactorYMultiplier.Value, smoothLookVector.x * 0.018f * MouseFactorZMultiplier.Value);
}
if (EnableFallingFactor.Value)
{
if (FallingFactorSmoothness.Value > 0f)
{
smoothVelocity = Vector3.Lerp(smoothVelocity, lastVelocity, Time.deltaTime * 2.8f / FallingFactorSmoothness.Value);
}
else
{
smoothVelocity = lastVelocity;
}
cameraContainerTransform.localRotation *= Quaternion.Euler(smoothVelocity.y, 0f, 0f);
}
if (EnableMoveFactor.Value)
{
if (MoveFactorSmoothness.Value > 0f)
{
smoothMove = Vector2.Lerp(smoothMove, lastMove, Time.deltaTime * 1.4f / MoveFactorSmoothness.Value);
}
else
{
smoothMove = lastMove;
}
if (Math.Abs(smoothMove.x) > 0.1f)
{
cameraContainerTransform.localRotation *= Quaternion.Euler(0f, 0f, (0f - smoothMove.x) * MoveFactorStrafeMultiplier.Value);
}
if (smoothMove.y > 0.1f)
{
cameraContainerTransform.localRotation *= Quaternion.Euler(smoothMove.y * 0.8f * MoveFactorForwardMultiplier.Value, 0f, 0f);
}
else if (smoothMove.y < -0.1f)
{
cameraContainerTransform.localRotation *= Quaternion.Euler(smoothMove.y * 0.8f * MoveFactorBackwardMultiplier.Value, 0f, 0f);
}
}
if (EnableFallShake.Value)
{
float num = lastVelocity.y - prevVelocity.y;
if ((num > FallShakeMinVelocity.Value) & (lastVelocity.y < 0.1f) & (lastVelocity.y > -0.1f))
{
fallShakeSmooth = (fallShakeAmount = Mathf.Clamp(Mathf.InverseLerp(FallShakeMinVelocity.Value, FallShakeMaxVelocity.Value, num), 0f, 1f));
}
fallShakeSmooth = Mathf.Lerp(fallShakeSmooth, 0f, Time.deltaTime * 1f);
cameraContainerTransform.localPosition += Random.insideUnitSphere * (fallShakeSmooth * 0.2f * FallShakeMultiplier.Value);
}
if (HealthCondition.Value)
{
float num2 = (HealthConditionSmoothing.Value ? ((___health > HealthConditionTriggerLimit.Value) ? 0f : (1f - (float)(___health / HealthConditionTriggerLimit.Value))) : ((___health > HealthConditionTriggerLimit.Value) ? 0f : 1f));
float num3 = num2;
if (num3 > 0f)
{
cameraContainerTransform.localPosition = Vector3.Lerp(SavedCameraPosition, cameraContainerTransform.localPosition, num3);
cameraContainerTransform.localRotation = Quaternion.Slerp(SavedCameraRotation, cameraContainerTransform.localRotation, num3);
}
else
{
RestoreCameraState();
}
}
}
}
}