Decompiled source of Not Gonna Sugarcoat It v1.1.0

Mods/NotGonnaSugarcoatIt.dll

Decompiled 10 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Il2Cpp;
using Il2CppFemur;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using NotGonnaSugarcoatIt;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(SugarcoatMod), "Not Gonna Sugarcoat It", "1.1.0", "AxisGames", null)]
[assembly: MelonGame("Boneloaf", "Gang Beasts")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NotGonnaSugarcoatIt
{
	public class SugarcoatMod : MelonMod
	{
		private class Copy
		{
			public Renderer Src;

			public SkinnedMeshRenderer Skin;

			public GameObject Go;

			public MeshRenderer Mr;

			public MeshFilter Mf;

			public Mesh Baked;
		}

		private class Culprit
		{
			public Actor Actor;

			public SharkActor Shark;

			public Component Comp
			{
				get
				{
					if (!((Object)(object)Actor != (Object)null))
					{
						return (Component)(object)Shark;
					}
					return (Component)(object)Actor;
				}
			}

			public bool Alive
			{
				get
				{
					if (!((Object)(object)Actor != (Object)null))
					{
						return (Object)(object)Shark != (Object)null;
					}
					return (Object)(object)Actor.bodyHandeler != (Object)null;
				}
			}

			public IntPtr Ptr
			{
				get
				{
					if (!((Object)(object)Actor != (Object)null))
					{
						if (!((Object)(object)Shark != (Object)null))
						{
							return IntPtr.Zero;
						}
						return ((Il2CppObjectBase)Shark).Pointer;
					}
					return ((Il2CppObjectBase)Actor).Pointer;
				}
			}

			public string Name
			{
				get
				{
					if (!((Object)(object)Actor != (Object)null))
					{
						return "the shark";
					}
					return $"player {Actor.playerID + 1}{(Actor.IsAI ? " (bot)" : "")}";
				}
			}
		}

		private static readonly Vector2 AvatarMin = new Vector2(0.04f, 0f);

		private static readonly Vector2 AvatarMax = new Vector2(0.96f, 0.7f);

		private const int AvatarTexW = 1104;

		private const int AvatarTexH = 840;

		private Texture2D imageTex;

		private AudioClip clip;

		private GameObject overlayRoot;

		private CanvasGroup group;

		private RawImage imageUi;

		private RawImage avatarUi;

		private Image flashUi;

		private AudioSource audio;

		private bool showing;

		private float showStart;

		private Culprit killer;

		private static readonly Vector3 StudioPos = new Vector3(0f, 20000f, 0f);

		private RenderTexture portraitTex;

		private Camera portraitCam;

		private Light keyLight;

		private Light fillLight;

		private GameObject studio;

		private int studioLayer = -1;

		private bool camSnapped;

		private Vector3 viewDir;

		private readonly List<Copy> copies = new List<Copy>();

		private MaterialPropertyBlock mpb;

		private bool shotsPending;

		private int shotIdx;

		private static readonly float[] ShotTimes = new float[3] { 0.5f, 1.5f, 3.2f };

		private MelonPreferences_Entry<float> prefVolume;

		private MelonPreferences_Entry<float> prefDuration;

		private MelonPreferences_Entry<float> prefFade;

		private MelonPreferences_Entry<float> prefSpeed;

		private MelonPreferences_Entry<float> prefMemory;

		private MelonPreferences_Entry<bool> prefEnabled;

		private IntPtr myPtr;

		private bool wasOut;

		private bool wasDead;

		private float lastHealth;

		private Culprit lastAttacker;

		private float lastAttackTime = -999f;

		private float actorScan;

		private readonly List<Actor> actors = new List<Actor>();

		private readonly List<SharkActor> sharks = new List<SharkActor>();

		private readonly HashSet<IntPtr> myBodies = new HashSet<IntPtr>();

		private readonly List<Rigidbody> myRbs = new List<Rigidbody>();

		private int errors;

		private float testFlagTimer = 8f;

		private bool testFlag;

		private bool testFlagChecked;

		private static BinaryReader Resource(string name)
		{
			return new BinaryReader(new GZipStream(typeof(SugarcoatMod).Assembly.GetManifestResourceStream(name) ?? throw new FileNotFoundException("embedded " + name), CompressionMode.Decompress));
		}

		private void LoadAssets()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			using (BinaryReader binaryReader = Resource("image.bin"))
			{
				int num = binaryReader.ReadInt32();
				int num2 = binaryReader.ReadInt32();
				byte[] array = binaryReader.ReadBytes(num * num2 * 4);
				imageTex = new Texture2D(num, num2, (TextureFormat)4, false);
				imageTex.LoadRawTextureData(new Il2CppStructArray<byte>(array));
				imageTex.Apply(false, true);
				((Texture)imageTex).wrapMode = (TextureWrapMode)1;
				((Object)imageTex).hideFlags = (HideFlags)61;
			}
			using BinaryReader binaryReader2 = Resource("sound.bin");
			int num3 = binaryReader2.ReadInt32();
			int num4 = binaryReader2.ReadInt32();
			int num5 = binaryReader2.ReadInt32();
			float[] array2 = new float[num5 * num3];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = (float)binaryReader2.ReadInt16() / 32768f;
			}
			clip = AudioClip.Create("lobotomy", num5, num3, num4, false);
			clip.SetData(new Il2CppStructArray<float>(array2), 0);
			((Object)clip).hideFlags = (HideFlags)61;
		}

		private bool EnsureOverlay()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)overlayRoot != (Object)null)
			{
				return true;
			}
			if ((Object)(object)imageTex == (Object)null)
			{
				return false;
			}
			overlayRoot = new GameObject("NotGonnaSugarcoatIt");
			Object.DontDestroyOnLoad((Object)(object)overlayRoot);
			Canvas obj = overlayRoot.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 32600;
			group = overlayRoot.AddComponent<CanvasGroup>();
			group.blocksRaycasts = false;
			group.interactable = false;
			imageUi = NewRaw("image", overlayRoot.transform, Vector2.zero, Vector2.one);
			imageUi.texture = (Texture)(object)imageTex;
			avatarUi = NewRaw("avatar", ((Component)imageUi).transform, AvatarMin, AvatarMax);
			GameObject val = new GameObject("flash");
			val.transform.SetParent(overlayRoot.transform, false);
			Stretch(val.AddComponent<RectTransform>(), Vector2.zero, Vector2.one);
			flashUi = val.AddComponent<Image>();
			((Graphic)flashUi).raycastTarget = false;
			((Graphic)flashUi).color = Color.white;
			audio = overlayRoot.AddComponent<AudioSource>();
			audio.playOnAwake = false;
			audio.spatialBlend = 0f;
			audio.ignoreListenerPause = true;
			audio.ignoreListenerVolume = false;
			audio.bypassReverbZones = true;
			audio.priority = 0;
			overlayRoot.SetActive(false);
			return true;
		}

		private static RawImage NewRaw(string name, Transform parent, Vector2 min, Vector2 max)
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			Stretch(val.AddComponent<RectTransform>(), min, max);
			RawImage obj = val.AddComponent<RawImage>();
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static void Stretch(RectTransform rt, Vector2 min, Vector2 max)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = min;
			rt.anchorMax = max;
			rt.offsetMin = Vector2.zero;
			rt.offsetMax = Vector2.zero;
		}

		private void Trigger(Culprit who, string why)
		{
			if (who != null && EnsureOverlay())
			{
				((MelonBase)this).LoggerInstance.Msg("Knockout screen (" + why + ") - showing " + who.Name);
				killer = who;
				showing = true;
				showStart = Time.unscaledTime;
				overlayRoot.SetActive(true);
				group.alpha = 1f;
				StartPortrait(who);
				avatarUi.texture = (Texture)(object)portraitTex;
				audio.Stop();
				audio.clip = clip;
				audio.pitch = Mathf.Clamp(prefSpeed.Value, 0.25f, 4f);
				audio.volume = Mathf.Clamp01(prefVolume.Value);
				if ((Object)(object)clip != (Object)null)
				{
					audio.Play();
				}
			}
		}

		public override void OnLateUpdate()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (!showing)
			{
				return;
			}
			try
			{
				float num = Time.unscaledTime - showStart;
				float num2 = Mathf.Max(0.3f, prefDuration.Value);
				float num3 = Mathf.Clamp(prefFade.Value, 0.05f, num2);
				float num4 = num2 - num3;
				((Graphic)flashUi).color = new Color(1f, 1f, 1f, Mathf.Clamp01(1f - num / 0.3f));
				bool enabled = num >= 0.45f || (int)(num / 0.075f) % 2 == 0;
				((Behaviour)imageUi).enabled = enabled;
				float num5 = ((num < num4) ? 1f : Mathf.Clamp01(1f - (num - num4) / num3));
				group.alpha = num5;
				audio.volume = Mathf.Clamp01(prefVolume.Value) * num5;
				UpdatePortrait(killer);
				ShotsTick(num);
				if (num >= num2)
				{
					Stop();
				}
			}
			catch (Exception ex)
			{
				if (errors++ < 10)
				{
					((MelonBase)this).LoggerInstance.Error("Effect: " + ex);
				}
				Stop();
			}
		}

		private void Stop()
		{
			showing = false;
			killer = null;
			if ((Object)(object)audio != (Object)null)
			{
				audio.Stop();
			}
			if ((Object)(object)overlayRoot != (Object)null)
			{
				overlayRoot.SetActive(false);
			}
			StopPortrait();
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			if (showing)
			{
				Stop();
			}
		}

		private int FindSpareLayer()
		{
			for (int num = 31; num >= 8; num--)
			{
				if (string.IsNullOrEmpty(LayerMask.LayerToName(num)))
				{
					return num;
				}
			}
			return 31;
		}

		private void EnsureStudio()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)studio != (Object)null))
			{
				if (studioLayer < 0)
				{
					studioLayer = FindSpareLayer();
				}
				studio = new GameObject("NotGonnaSugarcoatIt_Studio");
				Object.DontDestroyOnLoad((Object)(object)studio);
				studio.transform.position = StudioPos;
				portraitTex = new RenderTexture(1104, 840, 24, (RenderTextureFormat)0);
				portraitTex.antiAliasing = 4;
				portraitTex.Create();
				GameObject val = new GameObject("cam");
				val.transform.SetParent(studio.transform, false);
				portraitCam = val.AddComponent<Camera>();
				portraitCam.cullingMask = 1 << studioLayer;
				portraitCam.clearFlags = (CameraClearFlags)2;
				portraitCam.backgroundColor = new Color(0f, 0f, 0f, 0f);
				portraitCam.targetTexture = portraitTex;
				portraitCam.fieldOfView = 30f;
				portraitCam.nearClipPlane = 0.05f;
				portraitCam.farClipPlane = 100f;
				portraitCam.allowHDR = false;
				portraitCam.allowMSAA = true;
				portraitCam.depth = -50f;
				((Behaviour)portraitCam).enabled = false;
				keyLight = NewLight("key", 1.6f, (LightType)1);
				fillLight = NewLight("fill", 0.6f, (LightType)1);
			}
		}

		private Light NewLight(string name, float intensity, LightType type)
		{
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(studio.transform, false);
			Light obj = val.AddComponent<Light>();
			obj.type = type;
			obj.intensity = intensity;
			obj.color = Color.white;
			obj.cullingMask = 1 << studioLayer;
			obj.shadows = (LightShadows)0;
			((Behaviour)obj).enabled = false;
			return obj;
		}

		private void StartPortrait(Culprit who)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			EnsureStudio();
			StopPortrait();
			if (mpb == null)
			{
				mpb = new MaterialPropertyBlock();
			}
			foreach (Camera item in (Il2CppArrayBase<Camera>)(object)Camera.allCameras)
			{
				if ((Object)(object)item != (Object)null && ((Il2CppObjectBase)item).Pointer != ((Il2CppObjectBase)portraitCam).Pointer)
				{
					item.cullingMask &= ~(1 << studioLayer);
				}
			}
			foreach (Renderer componentsInChild in who.Comp.GetComponentsInChildren<Renderer>(false))
			{
				if ((Object)(object)componentsInChild == (Object)null || !componentsInChild.enabled)
				{
					continue;
				}
				SkinnedMeshRenderer val = ((Il2CppObjectBase)componentsInChild).TryCast<SkinnedMeshRenderer>();
				Mesh sharedMesh = null;
				if ((Object)(object)val == (Object)null)
				{
					if ((Object)(object)((Il2CppObjectBase)componentsInChild).TryCast<MeshRenderer>() == (Object)null)
					{
						continue;
					}
					MeshFilter component = ((Component)componentsInChild).GetComponent<MeshFilter>();
					if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null)
					{
						continue;
					}
					sharedMesh = component.sharedMesh;
				}
				GameObject val2 = new GameObject("copy");
				val2.layer = studioLayer;
				val2.transform.SetParent(studio.transform, false);
				Copy copy = new Copy
				{
					Src = componentsInChild,
					Skin = val,
					Go = val2
				};
				copy.Mf = val2.AddComponent<MeshFilter>();
				copy.Mr = val2.AddComponent<MeshRenderer>();
				((Renderer)copy.Mr).sharedMaterials = componentsInChild.sharedMaterials;
				((Renderer)copy.Mr).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)copy.Mr).receiveShadows = false;
				((Renderer)copy.Mr).lightProbeUsage = (LightProbeUsage)0;
				((Renderer)copy.Mr).reflectionProbeUsage = (ReflectionProbeUsage)0;
				if ((Object)(object)val != (Object)null)
				{
					copy.Baked = new Mesh();
					copy.Baked.MarkDynamic();
					copy.Mf.sharedMesh = copy.Baked;
				}
				else
				{
					copy.Mf.sharedMesh = sharedMesh;
				}
				copies.Add(copy);
			}
			camSnapped = false;
			((Behaviour)portraitCam).enabled = true;
			Light obj = keyLight;
			bool enabled = (((Behaviour)fillLight).enabled = true);
			((Behaviour)obj).enabled = enabled;
			UpdatePortrait(who);
		}

		private void UpdatePortrait(Culprit who)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: 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_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)portraitCam == (Object)null || copies.Count == 0 || who == null || !who.Alive)
			{
				return;
			}
			Vector3 val = Center(who);
			bool flag = false;
			Bounds val2 = default(Bounds);
			foreach (Copy copy in copies)
			{
				if ((Object)(object)copy.Src == (Object)null || (Object)(object)copy.Go == (Object)null)
				{
					continue;
				}
				Transform transform = ((Component)copy.Src).transform;
				if ((Object)(object)copy.Skin != (Object)null)
				{
					copy.Skin.BakeMesh(copy.Baked, true);
					copy.Go.transform.localScale = Vector3.one;
				}
				else
				{
					copy.Go.transform.localScale = transform.lossyScale;
				}
				copy.Go.transform.position = StudioPos + (transform.position - val);
				copy.Go.transform.rotation = transform.rotation;
				copy.Go.SetActive(copy.Src.enabled && ((Component)copy.Src).gameObject.activeInHierarchy);
				copy.Src.GetPropertyBlock(mpb);
				((Renderer)copy.Mr).SetPropertyBlock(mpb);
				if (copy.Go.activeSelf)
				{
					Bounds bounds = copy.Src.bounds;
					((Bounds)(ref bounds)).center = ((Bounds)(ref bounds)).center - val + StudioPos;
					if (!flag)
					{
						val2 = bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref val2)).Encapsulate(bounds);
					}
				}
			}
			if (flag)
			{
				Vector3 val3 = Facing(who);
				val3.y = 0f;
				if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
				{
					Actor val4 = Me();
					val3 = ((!((Object)(object)val4 != (Object)null) || !(((Il2CppObjectBase)val4).Pointer != who.Ptr)) ? (((Object)(object)Camera.main != (Object)null) ? (((Component)Camera.main).transform.position - val) : Vector3.forward) : (Center(val4) - val));
					val3.y = 0f;
				}
				if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
				{
					val3 = Vector3.forward;
				}
				Vector3 val5 = ((Vector3)(ref val3)).normalized + Vector3.up * 0.25f;
				val3 = ((Vector3)(ref val5)).normalized;
				viewDir = (camSnapped ? Vector3.Slerp(viewDir, val3, Time.unscaledDeltaTime * 4f) : val3);
				float num = 1.3142858f;
				float num2 = Mathf.Tan(portraitCam.fieldOfView * 0.5f * ((float)Math.PI / 180f));
				val5 = ((Bounds)(ref val2)).extents;
				float magnitude = ((Vector3)(ref val5)).magnitude;
				float num3 = Mathf.Max(magnitude / num2, magnitude / (num2 * num)) * 0.95f + 0.3f;
				Vector3 val6 = ((Bounds)(ref val2)).center + viewDir * num3;
				Transform transform2 = ((Component)portraitCam).transform;
				if (!camSnapped)
				{
					transform2.position = val6;
					camSnapped = true;
				}
				else
				{
					transform2.position = Vector3.Lerp(transform2.position, val6, Time.unscaledDeltaTime * 10f);
				}
				transform2.rotation = Quaternion.LookRotation(((Bounds)(ref val2)).center - transform2.position, Vector3.up);
				portraitCam.aspect = num;
				((Component)keyLight).transform.rotation = Quaternion.LookRotation(-viewDir + transform2.right * 0.6f - Vector3.up * 0.8f);
				((Component)fillLight).transform.rotation = Quaternion.LookRotation(-viewDir - transform2.right * 0.8f + Vector3.up * 0.2f);
			}
		}

		private void StopPortrait()
		{
			foreach (Copy copy in copies)
			{
				if ((Object)(object)copy.Go != (Object)null)
				{
					Object.Destroy((Object)(object)copy.Go);
				}
				if ((Object)(object)copy.Baked != (Object)null)
				{
					Object.Destroy((Object)(object)copy.Baked);
				}
			}
			copies.Clear();
			if ((Object)(object)portraitCam != (Object)null)
			{
				((Behaviour)portraitCam).enabled = false;
			}
			if ((Object)(object)keyLight != (Object)null)
			{
				((Behaviour)keyLight).enabled = false;
			}
			if ((Object)(object)fillLight != (Object)null)
			{
				((Behaviour)fillLight).enabled = false;
			}
		}

		private void ShotsTick(float t)
		{
			if (shotsPending)
			{
				if (shotIdx >= ShotTimes.Length)
				{
					shotsPending = false;
					shotIdx = 0;
				}
				else if (!(t < ShotTimes[shotIdx]))
				{
					string text = Path.Combine(MelonEnvironment.UserDataDirectory, $"Sugarcoat_shot_{shotIdx}.png");
					ScreenCapture.CaptureScreenshot(text);
					((MelonBase)this).LoggerInstance.Msg("Saved " + text);
					shotIdx++;
				}
			}
		}

		public override void OnInitializeMelon()
		{
			MelonPreferences_Category val = MelonPreferences.CreateCategory("NotGonnaSugarcoatIt", "Not Gonna Sugarcoat It");
			prefEnabled = val.CreateEntry<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			prefVolume = val.CreateEntry<float>("Volume", 1f, (string)null, "0..1", false, false, (ValueValidator)null, (string)null);
			prefDuration = val.CreateEntry<float>("DurationSeconds", 2.5f, (string)null, "Total time on screen, sound included", false, false, (ValueValidator)null, (string)null);
			prefFade = val.CreateEntry<float>("FadeOutSeconds", 1f, (string)null, "Last part of the duration spent fading out (picture and sound)", false, false, (ValueValidator)null, (string)null);
			prefSpeed = val.CreateEntry<float>("SoundSpeed", 1.8f, (string)null, "Sound playback speed (1 = normal)", false, false, (ValueValidator)null, (string)null);
			prefMemory = val.CreateEntry<float>("AttackerMemorySeconds", 6f, (string)null, "How recent a hit has to be to count as the knockout", false, false, (ValueValidator)null, (string)null);
			try
			{
				LoadAssets();
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error("Couldn't load the image/sound: " + ex);
			}
			((MelonBase)this).LoggerInstance.Msg("Loaded. F9 = play the knockout screen now (test), Shift+F9 = same but with the shark.");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			myPtr = IntPtr.Zero;
			lastAttacker = null;
			actorScan = 0f;
			testFlagTimer = 8f;
		}

		private static Culprit Of(Actor a)
		{
			if (!((Object)(object)a != (Object)null))
			{
				return null;
			}
			return new Culprit
			{
				Actor = a
			};
		}

		private static Culprit Of(SharkActor s)
		{
			if (!((Object)(object)s != (Object)null))
			{
				return null;
			}
			return new Culprit
			{
				Shark = s
			};
		}

		public override void OnUpdate()
		{
			try
			{
				Keyboard current = Keyboard.current;
				if (current != null && ((ButtonControl)current.f9Key).wasPressedThisFrame)
				{
					bool flag = ((ButtonControl)current.leftShiftKey).isPressed || ((ButtonControl)current.rightShiftKey).isPressed;
					Culprit culprit = (flag ? Of(NearestShark()) : (Of(NearestOther()) ?? Of(Me())));
					if (culprit == null)
					{
						((MelonBase)this).LoggerInstance.Msg(flag ? "No shark on this map." : "No beasts around.");
					}
					else
					{
						Trigger(culprit, "F9 test");
					}
				}
				TestFlagTick();
				if (!prefEnabled.Value)
				{
					return;
				}
				Actor val = Me();
				if (!((Object)(object)val == (Object)null))
				{
					if (((Il2CppObjectBase)val).Pointer != myPtr)
					{
						myPtr = ((Il2CppObjectBase)val).Pointer;
						wasOut = IsOut(val);
						wasDead = IsDead(val);
						lastHealth = Health(val);
						lastAttacker = null;
						CacheMyBodies(val);
					}
					TrackAttackers(val);
					bool flag2 = lastAttacker != null && lastAttacker.Alive && Time.unscaledTime - lastAttackTime <= prefMemory.Value;
					bool flag3 = IsOut(val);
					bool flag4 = IsDead(val);
					if (flag3 && !wasOut)
					{
						Trigger(flag2 ? lastAttacker : Of(val), flag2 ? ("knocked out by " + lastAttacker.Name) : "knocked yourself out");
					}
					else if (flag4 && !wasDead && flag2 && (Object)(object)lastAttacker.Shark != (Object)null && !showing)
					{
						Trigger(lastAttacker, "eaten by the shark");
					}
					wasOut = flag3;
					wasDead = flag4;
				}
			}
			catch (Exception ex)
			{
				if (errors++ < 10)
				{
					((MelonBase)this).LoggerInstance.Error("Update: " + ex);
				}
			}
		}

		private static bool IsOut(Actor a)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			return (int)a.actorState == 2;
		}

		private static bool IsDead(Actor a)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			return (int)a.actorState == 1;
		}

		private static float Health(Actor a)
		{
			if (!((Object)(object)a.statusHandeler != (Object)null))
			{
				return 0f;
			}
			return a.statusHandeler.health;
		}

		private void Rescan()
		{
			if (Time.unscaledTime - actorScan <= 0.5f && actorScan <= Time.unscaledTime)
			{
				return;
			}
			actorScan = Time.unscaledTime;
			actors.Clear();
			Il2CppArrayBase<Actor> val = Object.FindObjectsOfType<Actor>();
			for (int i = 0; i < val.Length; i++)
			{
				if ((Object)(object)val[i] != (Object)null)
				{
					actors.Add(val[i]);
				}
			}
			sharks.Clear();
			Il2CppArrayBase<SharkActor> val2 = Object.FindObjectsOfType<SharkActor>();
			for (int j = 0; j < val2.Length; j++)
			{
				if ((Object)(object)val2[j] != (Object)null)
				{
					sharks.Add(val2[j]);
				}
			}
		}

		private List<Actor> Actors()
		{
			Rescan();
			actors.RemoveAll((Actor a) => (Object)(object)a == (Object)null || (Object)(object)a.bodyHandeler == (Object)null || !((Component)a).gameObject.activeInHierarchy);
			return actors;
		}

		private List<SharkActor> Sharks()
		{
			Rescan();
			sharks.RemoveAll((SharkActor s) => (Object)(object)s == (Object)null || !((Component)s).gameObject.activeInHierarchy);
			return sharks;
		}

		private Actor Me()
		{
			Actor val = null;
			foreach (Actor item in Actors())
			{
				if (item.IsLocal && !item.IsAI && ((Object)(object)val == (Object)null || item.playerID < val.playerID))
				{
					val = item;
				}
			}
			return val;
		}

		private Actor NearestOther()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			Actor val = Me();
			Actor result = null;
			float num = float.MaxValue;
			foreach (Actor item in Actors())
			{
				if (!((Object)(object)val != (Object)null) || !(((Il2CppObjectBase)item).Pointer == ((Il2CppObjectBase)val).Pointer))
				{
					float num2 = (((Object)(object)val != (Object)null) ? Vector3.Distance(Center(item), Center(val)) : 0f);
					if (num2 < num)
					{
						num = num2;
						result = item;
					}
				}
			}
			return result;
		}

		private SharkActor NearestShark()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			Actor val = Me();
			SharkActor result = null;
			float num = float.MaxValue;
			foreach (SharkActor item in Sharks())
			{
				float num2 = (((Object)(object)val != (Object)null) ? Vector3.Distance(SharkCenter(item), Center(val)) : 0f);
				if (num2 < num)
				{
					num = num2;
					result = item;
				}
			}
			return result;
		}

		private void CacheMyBodies(Actor me)
		{
			myBodies.Clear();
			myRbs.Clear();
			foreach (Rigidbody componentsInChild in ((Component)me).GetComponentsInChildren<Rigidbody>(true))
			{
				if (!((Object)(object)componentsInChild == (Object)null))
				{
					myBodies.Add(((Il2CppObjectBase)componentsInChild).Pointer);
					myRbs.Add(componentsInChild);
				}
			}
		}

		private static Rigidbody Part(BodyPart p)
		{
			if (p == null)
			{
				return null;
			}
			return p.PartRigidbody;
		}

		private static Vector3 Center(Actor a)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			BodyHandeler bodyHandeler = a.bodyHandeler;
			Rigidbody val = (((Object)(object)bodyHandeler != (Object)null) ? (Part(bodyHandeler.Chest) ?? Part(bodyHandeler.Hips) ?? Part(bodyHandeler.Head)) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return ((Component)a).transform.position;
			}
			return val.worldCenterOfMass;
		}

		private static Vector3 SharkCenter(SharkActor s)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody val = s.torso ?? s.head;
			if (!((Object)(object)val != (Object)null))
			{
				return ((Component)s).transform.position;
			}
			return val.worldCenterOfMass;
		}

		private static Vector3 Center(Culprit c)
		{
			//IL_0020: 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)
			if (!((Object)(object)c.Actor != (Object)null))
			{
				return SharkCenter(c.Shark);
			}
			return Center(c.Actor);
		}

		private static Vector3 Facing(Culprit c)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)c.Shark != (Object)null)
			{
				SharkActor shark = c.Shark;
				Vector3 val = (((Object)(object)shark.head != (Object)null) ? shark.head.worldCenterOfMass : SharkCenter(shark));
				Vector3 val2 = (((Object)(object)shark.tailEnd != (Object)null) ? shark.tailEnd.worldCenterOfMass : (((Object)(object)shark.tailMid != (Object)null) ? shark.tailMid.worldCenterOfMass : SharkCenter(shark)));
				return val - val2;
			}
			BodyHandeler bodyHandeler = c.Actor.bodyHandeler;
			Rigidbody val3 = Part(bodyHandeler.LeftArm) ?? Part(bodyHandeler.LeftThigh);
			Rigidbody val4 = Part(bodyHandeler.RightArm) ?? Part(bodyHandeler.RightThigh);
			Rigidbody val5 = Part(bodyHandeler.Head) ?? Part(bodyHandeler.Chest);
			Rigidbody val6 = Part(bodyHandeler.Hips) ?? Part(bodyHandeler.Crotch);
			if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null)
			{
				return Vector3.zero;
			}
			Vector3 val7 = val4.worldCenterOfMass - val3.worldCenterOfMass;
			Vector3 val8 = val5.worldCenterOfMass - val6.worldCenterOfMass;
			return Vector3.Cross(val7, val8);
		}

		private void Credit(Culprit c)
		{
			lastAttacker = c;
			lastAttackTime = Time.unscaledTime;
		}

		private void TrackAttackers(Actor me)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (myRbs.Count == 0 || (Object)(object)myRbs[0] == (Object)null)
			{
				CacheMyBodies(me);
			}
			Vector3 val = Center(me);
			Actor val2 = null;
			float num = 2.5f;
			foreach (Actor item in Actors())
			{
				if (((Il2CppObjectBase)item).Pointer == ((Il2CppObjectBase)me).Pointer)
				{
					continue;
				}
				BodyHandeler bodyHandeler = item.bodyHandeler;
				if ((Object)(object)bodyHandeler == (Object)null)
				{
					continue;
				}
				float num2 = Vector3.Distance(Center(item), val);
				if (num2 < num)
				{
					num = num2;
					val2 = item;
				}
				if (!(num2 > 4f))
				{
					Rigidbody leftGrabRigidbody = bodyHandeler.leftGrabRigidbody;
					Rigidbody rightGrabRigidbody = bodyHandeler.rightGrabRigidbody;
					if (((Object)(object)leftGrabRigidbody != (Object)null && myBodies.Contains(((Il2CppObjectBase)leftGrabRigidbody).Pointer)) || ((Object)(object)rightGrabRigidbody != (Object)null && myBodies.Contains(((Il2CppObjectBase)rightGrabRigidbody).Pointer)))
					{
						Credit(Of(item));
					}
					else if (FistHits(Part(bodyHandeler.LeftHand)) || FistHits(Part(bodyHandeler.RightHand)))
					{
						Credit(Of(item));
					}
				}
			}
			foreach (SharkActor item2 in Sharks())
			{
				Rigidbody rigidbodyInMouth = item2.rigidbodyInMouth;
				if (((Object)(object)rigidbodyInMouth != (Object)null && myBodies.Contains(((Il2CppObjectBase)rigidbodyInMouth).Pointer)) || Touching(item2.jaw, 0.9f) || Touching(item2.head, 0.9f))
				{
					Credit(Of(item2));
				}
			}
			float num3 = Health(me);
			if (num3 < lastHealth - 0.5f && Time.unscaledTime - lastAttackTime > 0.4f && (Object)(object)val2 != (Object)null)
			{
				Credit(Of(val2));
			}
			lastHealth = num3;
		}

		private bool Touching(Rigidbody part, float range)
		{
			//IL_000c: 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_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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)part == (Object)null)
			{
				return false;
			}
			Vector3 worldCenterOfMass = part.worldCenterOfMass;
			foreach (Rigidbody myRb in myRbs)
			{
				if ((Object)(object)myRb != (Object)null)
				{
					Vector3 val = myRb.worldCenterOfMass - worldCenterOfMass;
					if (((Vector3)(ref val)).sqrMagnitude < range * range)
					{
						return true;
					}
				}
			}
			return false;
		}

		private bool FistHits(Rigidbody fist)
		{
			//IL_000c: 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_0013: 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)
			//IL_0038: 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_003f: 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)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)fist == (Object)null)
			{
				return false;
			}
			Vector3 worldCenterOfMass = fist.worldCenterOfMass;
			Vector3 velocity = fist.velocity;
			foreach (Rigidbody myRb in myRbs)
			{
				if ((Object)(object)myRb == (Object)null)
				{
					continue;
				}
				Vector3 val = velocity - myRb.velocity;
				if (!(((Vector3)(ref val)).sqrMagnitude < 9f))
				{
					Vector3 val2 = myRb.worldCenterOfMass - worldCenterOfMass;
					if (((Vector3)(ref val2)).sqrMagnitude < 0.20249999f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private void TestFlagTick()
		{
			if (!testFlagChecked)
			{
				testFlagChecked = true;
				testFlag = File.Exists(Path.Combine(MelonEnvironment.UserDataDirectory, "Sugarcoat_test.flag"));
			}
			if (testFlag && !(testFlagTimer < 0f))
			{
				testFlagTimer -= Time.unscaledDeltaTime;
				if (testFlagTimer < 0f && (Object)(object)Me() != (Object)null)
				{
					Trigger(Of(NearestOther()) ?? Of(Me()), "test flag");
					shotsPending = true;
				}
				else if (testFlagTimer < 0f)
				{
					testFlagTimer = 2f;
				}
			}
		}
	}
}