using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("Niko666")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Enhance and modify vanilla weapon recoil effects as you wish. Successor of ZLinearOomph and XRotateOomph.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Niko666.UniversalRecoilControl")]
[assembly: AssemblyTitle("UniversalRecoilControl")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
{
}
}
}
namespace Niko666
{
[BepInProcess("h3vr.exe")]
[BepInPlugin("Niko666.UniversalRecoilControl", "UniversalRecoilControl", "1.0.0")]
public class UniversalRecoilControl : BaseUnityPlugin
{
public static Dictionary<string, WeaponSettings> WeaponOverrides = new Dictionary<string, WeaponSettings>();
public ConfigEntry<float> configXAxisRotateMultiplyAmount;
public ConfigEntry<float> configXAxisRotateAddendAmount;
public ConfigEntry<float> configYAxisRotateMultiplyAmount;
public ConfigEntry<float> configYAxisRotateAddendAmount;
public ConfigEntry<float> configZAxisRotateMultiplyAmount;
public ConfigEntry<float> configZAxisRotateAddendAmount;
public ConfigEntry<float> configZAxisLinearMultiplyAmount;
public ConfigEntry<float> configZAxisLinearAddendAmount;
public ConfigEntry<float> configXYAxisLinearMultiplyAmount;
public ConfigEntry<float> configXYAxisLinearAddendAmount;
private const float DefaultXAxisRotateMultiplyAmount = 1.1f;
private const float DefaultXAxisRotateAddendAmount = 1f;
private const float DefaultYAxisRotateMultiplyAmount = 1.1f;
private const float DefaultYAxisRotateAddendAmount = 0.5f;
private const float DefaultZAxisRotateMultiplyAmount = 1.1f;
private const float DefaultZAxisRotateAddendAmount = 0.5f;
private const float DefaultZAxisLinearMultiplyAmount = 1.5f;
private const float DefaultZAxisLinearAddendAmount = 0.01f;
private const float DefaultXYAxisLinearMultiplyAmount = 1f;
private const float DefaultXYAxisLinearAddendAmount = 0f;
public const string Id = "Niko666.UniversalRecoilControl";
public static UniversalRecoilControl Instance { get; private set; }
internal static ManualLogSource Logger { get; private set; }
public static string Name => "UniversalRecoilControl";
public static string Version => "1.0.0";
public void Awake()
{
Instance = this;
configXAxisRotateMultiplyAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "XAxisRotateMultiplyAmount", 1.1f, "Multiply the recoil rotates on X-Axis (Pitch Up/Down). 1 being H3VR defaults.");
configXAxisRotateAddendAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "XAxisRotateAddendAmount", 1f, "The amount of rotates which will always get added on X-Axis so weaker firearms will still have some rotates");
configYAxisRotateMultiplyAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "YAxisRotateMultiplyAmount", 1.1f, "Multiply the recoil rotates on Y-Axis (Yaw Left/Right). 1 being H3VR defaults.");
configYAxisRotateAddendAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "YAxisRotateAddendAmount", 0.5f, "The (random) amount of rotates which will always get added on Y-Axis so weaker firearms will still have some rotates");
configZAxisRotateMultiplyAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ZAxisRotateMultiplyAmount", 1.1f, "Multiply the recoil rotates on Z-Axis (Roll Left/Right). 1 being H3VR defaults.");
configZAxisRotateAddendAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ZAxisRotateAddendAmount", 0.5f, "The (random) amount of rotates which will always get added on Z-Axis so weaker firearms will still have some rotates");
configZAxisLinearMultiplyAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ZAxisLinearMultiplyAmount", 1.5f, "Multiply the recoil linear movement on Z-Axis (Back/Forward). 1 being H3VR defaults.");
configZAxisLinearAddendAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ZAxisLinearAddendAmount", 0.01f, "The amount of linear movements which will always get added on Z-Axis so weaker firearms will still have some movements");
configXYAxisLinearMultiplyAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "XYAxisLinearMultiplyAmount", 1f, "Multiply the recoil linear movement on X/Y-Axis (Up/Down, Left/Right). 1 being H3VR defaults.");
configXYAxisLinearAddendAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "XYAxisLinearAddendAmount", 0f, "The amount of linear movements which will always get added on X/Y-Axis so weaker firearms will still have some movements");
Logger = ((BaseUnityPlugin)this).Logger;
LoadJsonConfig();
Harmony.CreateAndPatchAll(typeof(UniversalRecoilControlPatch), (string)null);
Logger.LogMessage((object)$"UniversalRecoilControl loaded. Overrides for {WeaponOverrides.Count} weapons found.");
}
private void LoadJsonConfig()
{
Logger = ((BaseUnityPlugin)this).Logger;
try
{
string directoryName = Path.GetDirectoryName(Paths.BepInExConfigPath);
if (string.IsNullOrEmpty(directoryName))
{
Logger.LogError((object)"Failed to get config directory path.");
return;
}
string path = Path.Combine(directoryName, "Niko666.UniversalRecoilControl.json");
if (!File.Exists(path))
{
Logger.LogInfo((object)"Config file not found. Creating default config...");
CreateDefaultJsonConfig(path);
}
RecoilConfigData recoilConfigData = JsonConvert.DeserializeObject<RecoilConfigData>(File.ReadAllText(path));
if (recoilConfigData != null && recoilConfigData.WeaponOverrides != null)
{
WeaponOverrides = recoilConfigData.WeaponOverrides;
Logger.LogInfo((object)$"Successfully loaded {WeaponOverrides.Count} weapon overrides.");
}
}
catch (Exception ex)
{
Logger.LogError((object)("Error loading config: " + ex.Message + "\n" + ex.StackTrace));
}
}
private void CreateDefaultJsonConfig(string path)
{
Logger = ((BaseUnityPlugin)this).Logger;
try
{
string directoryName = Path.GetDirectoryName(path);
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
string contents = JsonConvert.SerializeObject((object)new RecoilConfigData
{
WeaponOverrides = new Dictionary<string, WeaponSettings>
{
{
"ExampleObjectID1",
new WeaponSettings
{
XAxisRotateMultiplyAmount = 1f,
XAxisRotateAddendAmount = 0f,
YAxisRotateMultiplyAmount = 1f,
YAxisRotateAddendAmount = 0f,
ZAxisRotateMultiplyAmount = 1f,
ZAxisRotateAddendAmount = 0f,
ZAxisLinearMultiplyAmount = 1f,
ZAxisLinearAddendAmount = 0f,
XYAxisLinearMultiplyAmount = 1f,
XYAxisLinearAddendAmount = 0f
}
},
{
"ExampleObjectID2",
new WeaponSettings
{
XAxisRotateMultiplyAmount = 1f,
XAxisRotateAddendAmount = 0f,
YAxisRotateMultiplyAmount = 1f,
YAxisRotateAddendAmount = 0f,
ZAxisRotateMultiplyAmount = 1f,
ZAxisRotateAddendAmount = 0f,
ZAxisLinearMultiplyAmount = 1f,
ZAxisLinearAddendAmount = 0f,
XYAxisLinearMultiplyAmount = 1f,
XYAxisLinearAddendAmount = 0f
}
}
}
}, (Formatting)1);
File.WriteAllText(path, contents);
Logger.LogInfo((object)("Created default config at: " + path));
}
catch (Exception ex)
{
Logger.LogError((object)("Error creating default config: " + ex.Message + "\n" + ex.StackTrace));
}
}
}
public class RecoilConfigData
{
public Dictionary<string, WeaponSettings> WeaponOverrides { get; set; }
}
public class WeaponSettings
{
public float? XAxisRotateMultiplyAmount { get; set; }
public float? XAxisRotateAddendAmount { get; set; }
public float? YAxisRotateMultiplyAmount { get; set; }
public float? YAxisRotateAddendAmount { get; set; }
public float? ZAxisRotateMultiplyAmount { get; set; }
public float? ZAxisRotateAddendAmount { get; set; }
public float? ZAxisLinearMultiplyAmount { get; set; }
public float? ZAxisLinearAddendAmount { get; set; }
public float? XYAxisLinearMultiplyAmount { get; set; }
public float? XYAxisLinearAddendAmount { get; set; }
}
internal static class UniversalRecoilControlPatch
{
[HarmonyPatch(typeof(FVRFireArm), "Recoil")]
[HarmonyPostfix]
public static void Modifier(FVRFireArm __instance, FVRFireArmRecoilProfile overrideprofile = null)
{
//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
//IL_0302: Unknown result type (might be due to invalid IL or missing references)
//IL_0307: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null || (Object)(object)((FVRPhysicalObject)__instance).ObjectWrapper == (Object)null)
{
return;
}
string itemID = ((FVRPhysicalObject)__instance).ObjectWrapper.ItemID;
if (string.IsNullOrEmpty(itemID))
{
return;
}
float value = UniversalRecoilControl.Instance.configXAxisRotateMultiplyAmount.Value;
float value2 = UniversalRecoilControl.Instance.configXAxisRotateAddendAmount.Value;
float value3 = UniversalRecoilControl.Instance.configYAxisRotateMultiplyAmount.Value;
float value4 = UniversalRecoilControl.Instance.configYAxisRotateAddendAmount.Value;
float value5 = UniversalRecoilControl.Instance.configZAxisRotateMultiplyAmount.Value;
float value6 = UniversalRecoilControl.Instance.configZAxisRotateAddendAmount.Value;
float value7 = UniversalRecoilControl.Instance.configZAxisLinearMultiplyAmount.Value;
float value8 = UniversalRecoilControl.Instance.configZAxisLinearAddendAmount.Value;
float value9 = UniversalRecoilControl.Instance.configXYAxisLinearMultiplyAmount.Value;
float value10 = UniversalRecoilControl.Instance.configXYAxisLinearAddendAmount.Value;
if (UniversalRecoilControl.WeaponOverrides.TryGetValue(itemID, out var value11))
{
if (value11.XAxisRotateMultiplyAmount.HasValue)
{
value = value11.XAxisRotateMultiplyAmount.Value;
}
if (value11.XAxisRotateAddendAmount.HasValue)
{
value2 = value11.XAxisRotateAddendAmount.Value;
}
if (value11.YAxisRotateMultiplyAmount.HasValue)
{
value3 = value11.YAxisRotateMultiplyAmount.Value;
}
if (value11.YAxisRotateAddendAmount.HasValue)
{
value4 = value11.YAxisRotateAddendAmount.Value;
}
if (value11.ZAxisRotateMultiplyAmount.HasValue)
{
value5 = value11.ZAxisRotateMultiplyAmount.Value;
}
if (value11.ZAxisRotateAddendAmount.HasValue)
{
value6 = value11.ZAxisRotateAddendAmount.Value;
}
if (value11.ZAxisLinearMultiplyAmount.HasValue)
{
value7 = value11.ZAxisLinearMultiplyAmount.Value;
}
if (value11.ZAxisLinearAddendAmount.HasValue)
{
value8 = value11.ZAxisLinearAddendAmount.Value;
}
if (value11.XYAxisLinearMultiplyAmount.HasValue)
{
value9 = value11.XYAxisLinearMultiplyAmount.Value;
}
if (value11.XYAxisLinearAddendAmount.HasValue)
{
value10 = value11.XYAxisLinearAddendAmount.Value;
}
}
FVRFireArmRecoilProfile val;
if ((Object)(object)overrideprofile != (Object)null)
{
val = overrideprofile;
}
else
{
val = __instance.GetRecoilProfile();
if ((Object)(object)val == (Object)null)
{
return;
}
}
__instance.m_recoilX = value2 + __instance.m_recoilX * value;
__instance.m_recoilY = Random.Range(0f - value4, value4) + __instance.m_recoilY * value3;
__instance.m_recoilZ = Random.Range(0f - value6, value6) + __instance.m_recoilZ * value5;
_ = __instance.m_recoilPoseHolderLocalPosStart;
__instance.m_recoilLinearZ = value8 + Mathf.Clamp(__instance.m_recoilLinearZ * value7, __instance.m_recoilPoseHolderLocalPosStart.z, __instance.m_recoilPoseHolderLocalPosStart.z + val.ZLinearMax * value7);
__instance.m_recoilLinearXY = Vector2.ClampMagnitude(__instance.m_recoilLinearXY, val.XYLinearMax * value9 + value10);
}
}
}