using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ComputerysModdingUtilities;
using DG.Tweening;
using HarmonyLib;
using UnityEngine;
[assembly: StraftatMod(true)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace NoCameraRoll;
[BepInPlugin("kev.nocameraroll", "No Camera Roll", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
internal static ConfigEntry<bool> DisableRoll;
internal static ConfigEntry<bool> DisableVaultShake;
internal static ConfigEntry<bool> DisableLandingShake;
internal static ConfigEntry<bool> DisableSlopeJumpShake;
internal static ConfigEntry<bool> DisableWallJumpShake;
internal static ConfigEntry<bool> DisableCeilingBumpShake;
private void Awake()
{
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
DisableRoll = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableCameraRoll", true, "Removes camera roll from strafing and mouse movement (also removes the wall-slide lean).");
DisableVaultShake = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableVaultShake", true, "Removes the camera shake when vaulting over an object.");
DisableLandingShake = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableLandingShake", true, "Removes the camera shake on landing, including the hard-landing camera dip.");
DisableSlopeJumpShake = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableSlopeJumpShake", true, "Removes the camera shake when jumping out of a slide.");
DisableWallJumpShake = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableWallJumpShake", false, "Removes the camera shake when wall jumping.");
DisableCeilingBumpShake = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableCeilingBumpShake", false, "Removes the camera shake when hitting a ceiling.");
new Harmony("kev.nocameraroll").PatchAll();
Log.LogInfo((object)"No Camera Roll loaded.");
}
}
internal static class ShakeGate
{
private static Tweener Punch(bool disabled, Transform t, Vector3 punch, float duration, int vibrato, float elasticity)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
return (!disabled) ? ShortcutExtensions.DOPunchRotation(t, punch, duration, vibrato, elasticity) : null;
}
public static Tweener Vault(Transform t, Vector3 p, float d, int v, float e)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return Punch(Plugin.DisableVaultShake.Value, t, p, d, v, e);
}
public static Tweener Landing(Transform t, Vector3 p, float d, int v, float e)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return Punch(Plugin.DisableLandingShake.Value, t, p, d, v, e);
}
public static Tweener SlopeJump(Transform t, Vector3 p, float d, int v, float e)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return Punch(Plugin.DisableSlopeJumpShake.Value, t, p, d, v, e);
}
public static Tweener WallJump(Transform t, Vector3 p, float d, int v, float e)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return Punch(Plugin.DisableWallJumpShake.Value, t, p, d, v, e);
}
public static Tweener Ceiling(Transform t, Vector3 p, float d, int v, float e)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return Punch(Plugin.DisableCeilingBumpShake.Value, t, p, d, v, e);
}
public static Tween HardLanding(Transform t, Vector3 end, float d, RotateMode mode)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
return (Tween)(object)((!Plugin.DisableLandingShake.Value) ? ShortcutExtensions.DOLocalRotate(t, end, d, mode) : null);
}
}
internal static class CallSwapper
{
internal static readonly MethodInfo DOPunchRotation = AccessTools.Method(typeof(ShortcutExtensions), "DOPunchRotation", new Type[5]
{
typeof(Transform),
typeof(Vector3),
typeof(float),
typeof(int),
typeof(float)
}, (Type[])null);
internal static readonly MethodInfo DOLocalRotate = AccessTools.Method(typeof(ShortcutExtensions), "DOLocalRotate", new Type[4]
{
typeof(Transform),
typeof(Vector3),
typeof(float),
typeof(RotateMode)
}, (Type[])null);
internal static MethodInfo Gate(string name)
{
return AccessTools.Method(typeof(ShakeGate), name, (Type[])null, (Type[])null);
}
internal static List<CodeInstruction> Swap(IEnumerable<CodeInstruction> instructions, string where, MethodInfo target, params MethodInfo[] replacements)
{
List<CodeInstruction> list = instructions.ToList();
List<CodeInstruction> list2 = list.Where((CodeInstruction ci) => CodeInstructionExtensions.Calls(ci, target)).ToList();
if (list2.Count != replacements.Length)
{
Plugin.Log.LogWarning((object)$"{where}: expected {replacements.Length} call(s) to {target.Name}, found {list2.Count}. Leaving it unpatched.");
return list;
}
for (int num = 0; num < list2.Count; num++)
{
list2[num].opcode = OpCodes.Call;
list2[num].operand = replacements[num];
}
return list;
}
}
[HarmonyPatch(typeof(FirstPersonController), "SideTilt")]
internal static class NoCameraRollPatch
{
private static bool Prefix(ref float ___rotationZ)
{
if (!Plugin.DisableRoll.Value)
{
return true;
}
___rotationZ = 0f;
return false;
}
}
[HarmonyPatch(typeof(FirstPersonController), "CheckForVault")]
internal static class VaultShakePatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
return CallSwapper.Swap(instructions, "CheckForVault", CallSwapper.DOPunchRotation, CallSwapper.Gate("Vault"));
}
}
[HarmonyPatch(typeof(FirstPersonController), "ApplyFinalMovements")]
internal static class ApplyFinalMovementsShakePatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> instructions2 = CallSwapper.Swap(instructions, "ApplyFinalMovements", CallSwapper.DOPunchRotation, CallSwapper.Gate("SlopeJump"), CallSwapper.Gate("Landing"));
return CallSwapper.Swap(instructions2, "ApplyFinalMovements", CallSwapper.DOLocalRotate, CallSwapper.Gate("HardLanding"));
}
}
[HarmonyPatch(typeof(FirstPersonController), "Jump")]
internal static class JumpShakePatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
return CallSwapper.Swap(instructions, "Jump", CallSwapper.DOPunchRotation, CallSwapper.Gate("WallJump"), CallSwapper.Gate("SlopeJump"), CallSwapper.Gate("SlopeJump"), CallSwapper.Gate("SlopeJump"));
}
}
[HarmonyPatch(typeof(FirstPersonController), "OnControllerColliderHit")]
internal static class CeilingShakePatch
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
return CallSwapper.Swap(instructions, "OnControllerColliderHit", CallSwapper.DOPunchRotation, CallSwapper.Gate("Ceiling"), CallSwapper.Gate("Ceiling"));
}
}