Decompiled source of Suppression v2.1.2

Mods/SuppressionMod.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using HarmonyLib;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using MelonLoader;
using Microsoft.CodeAnalysis;
using SuppressionMod;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "Suppression", "2.1.0", "YourName", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SuppressionMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SuppressionMod")]
[assembly: AssemblyTitle("SuppressionMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[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 SuppressionMod
{
	public class Core : MelonMod
	{
		private const bool DebugLog = true;

		private const float NearMissRadius = 4.2f;

		private const float OwnBulletHandDist = 0.5f;

		private const float HoldTime = 0.35f;

		private const float DecayTime = 3f;

		private const float SmoothingSpeed = 12f;

		private const float MaxVignetteAlpha = 0.95f;

		private const float MaxFlatDarken = 0.35f;

		private const float MinLowpassHz = 900f;

		private const float MinVolumeScale = 0.55f;

		private const float MaxTrackingDist = 75f;

		private static float _target;

		private static float _current;

		private static float _holdTimer;

		private static int _debugCount;

		private GameObject _overlayRoot;

		private Image _vignette;

		private Image _flat;

		private Sprite _vignetteSprite;

		private AudioListener _listener;

		private AudioLowPassFilter _lowpass;

		private float _baseVolume = 1f;

		private bool _volumeCaptured;

		private float _listenerSearchTimer;

		public override void OnInitializeMelon()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(Projectile), "SetBulletObject", (Type[])null, (Type[])null);
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Core).GetMethod("SetBulletObjectPostfix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("Patched Projectile.SetBulletObject with trajectory ray checking.");
			}
			catch (Exception value)
			{
				((MelonBase)this).LoggerInstance.Error($"Projectile patch failed: {value}");
			}
			TryPatchPlayerDamage();
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			_target = (_current = 0f);
			_overlayRoot = null;
			_listener = null;
			_lowpass = null;
			_volumeCaptured = false;
		}

		public override void OnUpdate()
		{
			if (_holdTimer > 0f)
			{
				_holdTimer -= Time.deltaTime;
			}
			else
			{
				_target = Mathf.MoveTowards(_target, 0f, Time.deltaTime / 3f);
			}
			_current = Mathf.Lerp(_current, _target, 1f - Mathf.Exp(-12f * Time.deltaTime));
			if (_current < 0.001f && _target <= 0f)
			{
				_current = 0f;
			}
			EnsureOverlay();
			ApplyVisuals(_current);
			ApplyAudio(_current);
		}

		private static void Suppress(float amount)
		{
			_target = Mathf.Clamp01(_target + amount);
			_holdTimer = 0.35f;
			_current = Mathf.Max(_current, _target * 0.8f);
		}

		private static void SetBulletObjectPostfix(Projectile __instance, Transform startTransform, Rigidbody EmittingRigidbody, TriggerRefProxy proxy)
		{
			//IL_007e: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)__instance == (Object)null || IsLocalPlayersBullet(startTransform, EmittingRigidbody, proxy))
				{
					return;
				}
				if (_debugCount++ < 30)
				{
					MelonLogger.Msg("[Suppression] Remote bullet spawned. Origin proxy: " + (((Object)(object)proxy != (Object)null) ? ((Object)proxy).name : "null"));
				}
				Transform head = GetHead();
				if ((Object)(object)head == (Object)null)
				{
					return;
				}
				Vector3 val = (((Object)(object)startTransform != (Object)null) ? startTransform.position : ((Component)__instance).transform.position);
				Vector3 val2 = (((Object)(object)startTransform != (Object)null) ? startTransform.forward : ((Component)__instance).transform.forward);
				((Vector3)(ref val2)).Normalize();
				Vector3 position = head.position;
				float num = Vector3.Dot(position - val, val2);
				if (num > 0f && num < 75f)
				{
					Vector3 val3 = val + val2 * num;
					float num2 = Vector3.Distance(position, val3);
					if (num2 <= 4.2f)
					{
						float num3 = 1f - num2 / 4.2f;
						float num4 = 0.25f + 0.55f * num3 * num3 + ((num2 < 0.3f) ? 0.15f : 0f);
						Suppress(num4);
						MelonLogger.Msg($"[Suppression] NEAR MISS DETECTED! Passed {num2:F2}m from head. Added {num4:F2} suppression.");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[Suppression] postfix error: " + ex.Message);
			}
		}

		private void TryPatchPlayerDamage()
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			try
			{
				Type type = (from a in AppDomain.CurrentDomain.GetAssemblies()
					where a.GetName().Name.Contains("Assembly-CSharp") || a.GetName().Name.Contains("SLZ.Marrow")
					select a).SelectMany(delegate(Assembly a)
				{
					try
					{
						return a.GetTypes();
					}
					catch
					{
						return new Type[0];
					}
				}).FirstOrDefault((Type t) => t.Name == "Player_Health");
				MethodInfo methodInfo = type?.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "TakeDamage");
				if (methodInfo == null)
				{
					((MelonBase)this).LoggerInstance.Warning("Player_Health.TakeDamage not found - hit detection disabled.");
					return;
				}
				((MelonBase)this).HarmonyInstance.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Core).GetMethod("DamagePostfix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((MelonBase)this).LoggerInstance.Msg("Patched " + type.FullName + ".TakeDamage");
			}
			catch (Exception value)
			{
				((MelonBase)this).LoggerInstance.Error($"Damage patch failed: {value}");
			}
		}

		private static void DamagePostfix(float damage)
		{
			if (damage > 0f)
			{
				Suppress(1f);
			}
		}

		private static bool IsLocalPlayersBullet(Transform muzzle, Rigidbody emitter, TriggerRefProxy proxy)
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RigManager rigManager = Player.RigManager;
				if ((Object)(object)rigManager != (Object)null)
				{
					Transform transform = ((Component)rigManager).transform;
					if ((Object)(object)proxy != (Object)null && ((Component)proxy).transform.IsChildOf(transform))
					{
						return true;
					}
					if ((Object)(object)emitter != (Object)null && ((Component)emitter).transform.IsChildOf(transform))
					{
						return true;
					}
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)muzzle != (Object)null)
				{
					Hand[] array = (Hand[])(object)new Hand[2]
					{
						Player.LeftHand,
						Player.RightHand
					};
					foreach (Hand val in array)
					{
						if ((Object)(object)val == (Object)null)
						{
							continue;
						}
						GameObject objectInHand = Player.GetObjectInHand(val);
						if (!((Object)(object)objectInHand == (Object)null))
						{
							Transform transform2 = objectInHand.transform;
							if ((Object)(object)transform2 == (Object)(object)muzzle || muzzle.IsChildOf(transform2) || transform2.IsChildOf(muzzle))
							{
								return true;
							}
						}
					}
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)muzzle != (Object)null)
				{
					Vector3 position = muzzle.position;
					if (Vector3.Distance(position, ((Component)Player.LeftHand).transform.position) < 0.5f)
					{
						return true;
					}
					if (Vector3.Distance(position, ((Component)Player.RightHand).transform.position) < 0.5f)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static Transform GetHead()
		{
			try
			{
				if ((Object)(object)Player.Head != (Object)null)
				{
					return Player.Head;
				}
			}
			catch
			{
			}
			if (!((Object)(object)Camera.main != (Object)null))
			{
				return null;
			}
			return ((Component)Camera.main).transform;
		}

		private void EnsureOverlay()
		{
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_overlayRoot != (Object)null)
			{
				return;
			}
			Transform head = GetHead();
			if ((Object)(object)head == (Object)null)
			{
				return;
			}
			if ((Object)(object)_vignetteSprite == (Object)null)
			{
				Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
				{
					wrapMode = (TextureWrapMode)1
				};
				for (int i = 0; i < 64; i++)
				{
					for (int j = 0; j < 64; j++)
					{
						float num = ((float)j / 63f - 0.5f) * 2f;
						float num2 = ((float)i / 63f - 0.5f) * 2f;
						float num3 = Mathf.Sqrt(num * num + num2 * num2);
						float num4 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.25f, 1.1f, num3));
						val.SetPixel(j, i, new Color(0f, 0f, 0f, num4));
					}
				}
				val.Apply();
				_vignetteSprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
			}
			_overlayRoot = new GameObject("SuppressionOverlay");
			_overlayRoot.transform.SetParent(head, false);
			_overlayRoot.transform.localPosition = new Vector3(0f, 0f, 0.15f);
			_overlayRoot.transform.localRotation = Quaternion.identity;
			_overlayRoot.transform.localScale = Vector3.one * 0.0008f;
			Canvas obj = _overlayRoot.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)2;
			obj.sortingOrder = 32000;
			_overlayRoot.GetComponent<RectTransform>().sizeDelta = new Vector2(1200f, 1200f);
			_vignette = MakeImage("Vignette", _vignetteSprite);
			_flat = MakeImage("Flat", null);
			((Graphic)_vignette).color = new Color(0f, 0f, 0f, 0f);
			((Graphic)_flat).color = new Color(0f, 0f, 0f, 0f);
		}

		private Image MakeImage(string name, Sprite sprite)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(_overlayRoot.transform, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			obj.offsetMin = Vector2.zero;
			obj.offsetMax = Vector2.zero;
			Image obj2 = val.AddComponent<Image>();
			obj2.sprite = sprite;
			((Graphic)obj2).raycastTarget = false;
			return obj2;
		}

		private void ApplyVisuals(float i)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_overlayRoot == (Object)null) && !((Object)(object)_vignette == (Object)null) && !((Object)(object)_flat == (Object)null))
			{
				_overlayRoot.SetActive(i > 0.002f);
				((Graphic)_vignette).color = new Color(0f, 0f, 0f, i * 0.95f);
				((Graphic)_flat).color = new Color(0f, 0f, 0f, i * 0.35f);
			}
		}

		private void ApplyAudio(float i)
		{
			if ((Object)(object)_listener == (Object)null)
			{
				_listenerSearchTimer -= Time.deltaTime;
				if (_listenerSearchTimer > 0f)
				{
					return;
				}
				_listenerSearchTimer = 1f;
				_listener = Object.FindObjectOfType<AudioListener>();
				if ((Object)(object)_listener == (Object)null)
				{
					return;
				}
				_lowpass = ((Component)_listener).gameObject.GetComponent<AudioLowPassFilter>();
				if ((Object)(object)_lowpass == (Object)null)
				{
					_lowpass = ((Component)_listener).gameObject.AddComponent<AudioLowPassFilter>();
				}
				_lowpass.cutoffFrequency = 22000f;
				_lowpass.lowpassResonanceQ = 1f;
				((Behaviour)_lowpass).enabled = false;
			}
			if (!_volumeCaptured)
			{
				_baseVolume = AudioListener.volume;
				_volumeCaptured = true;
			}
			if (i <= 0.002f)
			{
				if ((Object)(object)_lowpass != (Object)null && ((Behaviour)_lowpass).enabled)
				{
					((Behaviour)_lowpass).enabled = false;
				}
				AudioListener.volume = _baseVolume;
			}
			else
			{
				((Behaviour)_lowpass).enabled = true;
				_lowpass.cutoffFrequency = Mathf.Exp(Mathf.Lerp(Mathf.Log(22000f), Mathf.Log(900f), i));
				AudioListener.volume = _baseVolume * Mathf.Lerp(1f, 0.55f, i);
			}
		}
	}
}