Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CaptainsHat v0.2.0
CaptainsHat/captainshat.dll
Decompiled 19 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CaptainsHat")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.1.0")] [assembly: AssemblyInformationalVersion("0.2.1")] [assembly: AssemblyProduct("CaptainsHat")] [assembly: AssemblyTitle("CaptainsHat")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.1.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.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = 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 CaptainsHat { internal static class CarriedProtection { internal static bool Applies<T>(IEnumerable<T>? slots, T? utilitySlot, bool alive, bool controlled, Predicate<T> isBeer) where T : class? { if (!alive || !controlled) { return false; } if (utilitySlot != null && isBeer(utilitySlot)) { return true; } if (slots == null) { return false; } foreach (T slot in slots) { if (isBeer(slot)) { return true; } } return false; } } internal readonly struct HatVertex { internal readonly float X; internal readonly float Y; internal readonly float Z; internal HatVertex(float x, float y, float z) { X = x; Y = y; Z = z; } } internal sealed class HatMeshData { internal readonly List<HatVertex> Vertices = new List<HatVertex>(); internal readonly List<int> Triangles = new List<int>(); internal void Face(int a, int b, int c) { Triangles.Add(a); Triangles.Add(b); Triangles.Add(c); } } internal static class HatGeometry { internal const int Segments = 64; internal static HatMeshData Crown() { return Rings(new float[5] { 0.045f, 0.078f, 0.125f, 0.16f, 0.177f }, new float[5] { 0.119f, 0.147f, 0.157f, 0.14f, 0.105f }, new float[5] { 0.104f, 0.125f, 0.129f, 0.115f, 0.086f }, worn: true); } internal static HatMeshData Band() { return Rings(new float[2] { 0.012f, 0.055f }, new float[2] { 0.12f, 0.124f }, new float[2] { 0.105f, 0.109f }, worn: false); } private static HatMeshData Rings(float[] heights, float[] widths, float[] depths, bool worn) { HatMeshData hatMeshData = new HatMeshData(); for (int i = 0; i < heights.Length; i++) { for (int j = 0; j < 64; j++) { double num = (double)j * Math.PI * 2.0 / 64.0; float num2 = (worn ? ((float)(0.005 * Math.Sin(num * 3.0) + 0.003 * Math.Cos(num * 5.0) - 0.008 * Math.Sin(num)) * (float)i / (float)(heights.Length - 1)) : 0f); hatMeshData.Vertices.Add(new HatVertex((float)Math.Cos(num) * widths[i], heights[i] + num2, (float)Math.Sin(num) * depths[i])); if (i != 0) { int a = (i - 1) * 64 + j; int num3 = (j + 1) % 64; int b = i * 64 + j; int num4 = i * 64 + num3; hatMeshData.Face(a, b, num4); hatMeshData.Face(a, num4, (i - 1) * 64 + num3); } } } int count = hatMeshData.Vertices.Count; hatMeshData.Vertices.Add(new HatVertex(0f, heights[0], 0f)); int count2 = hatMeshData.Vertices.Count; hatMeshData.Vertices.Add(new HatVertex(0f, heights[^1] + (worn ? 0.009f : 0f), 0f)); for (int k = 0; k < 64; k++) { int num5 = (k + 1) % 64; hatMeshData.Face(count, k, num5); hatMeshData.Face(count2, (heights.Length - 1) * 64 + num5, (heights.Length - 1) * 64 + k); } return hatMeshData; } internal static HatMeshData Visor() { HatMeshData hatMeshData = new HatMeshData(); for (int i = 0; i <= 40; i++) { double num = Math.PI * -24.0 / 25.0 + 2.8902652413026098 * (double)i / 40.0; float num2 = (float)Math.Cos(num); float num3 = (float)Math.Sin(num); float num4 = 0.025f - 0.013f * num3 * num3; hatMeshData.Vertices.Add(new HatVertex(num2 * 0.105f, num4, num3 * 0.096f - 0.015f)); hatMeshData.Vertices.Add(new HatVertex(num2 * 0.166f, num4 - 0.006f, num3 * 0.205f - 0.015f)); hatMeshData.Vertices.Add(new HatVertex(num2 * 0.105f, num4 - 0.007f, num3 * 0.096f - 0.015f)); hatMeshData.Vertices.Add(new HatVertex(num2 * 0.166f, num4 - 0.013f, num3 * 0.205f - 0.015f)); if (i != 0) { int num5 = (i - 1) * 4; int num6 = i * 4; hatMeshData.Face(num5, num6 + 1, num5 + 1); hatMeshData.Face(num5, num6, num6 + 1); hatMeshData.Face(num5 + 2, num5 + 3, num6 + 3); hatMeshData.Face(num5 + 2, num6 + 3, num6 + 2); hatMeshData.Face(num5 + 1, num6 + 3, num5 + 3); hatMeshData.Face(num5 + 1, num6 + 1, num6 + 3); hatMeshData.Face(num5, num5 + 2, num6 + 2); hatMeshData.Face(num5, num6 + 2, num6); } } hatMeshData.Face(0, 1, 3); hatMeshData.Face(0, 3, 2); int num7 = 160; hatMeshData.Face(num7, num7 + 3, num7 + 1); hatMeshData.Face(num7, num7 + 2, num7 + 3); return hatMeshData; } } internal static class HatItem { internal static Item Definition; internal static void Register() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0115: 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_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) Assembly assembly = ((object)Chainloader.PluginInfos["evaisa.lethallib"].Instance).GetType().Assembly; GameObject val = (GameObject)assembly.GetType("LethalLib.Modules.NetworkPrefabs").GetMethod("CreateNetworkPrefab", new Type[1] { typeof(string) }).Invoke(null, new object[1] { "achachala.rocketbeer.Bottle.v1" }); uint num = 2166136261u; string text = "achachala.rocketbeer.Bottle.v1"; foreach (char c in text) { num = (num ^ c) * 16777619; } typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).SetValue(val.GetComponent<NetworkObject>(), num); val.tag = "PhysicsProp"; val.layer = LayerMask.NameToLayer("Props"); Rigidbody val2 = val.AddComponent<Rigidbody>(); val2.isKinematic = true; val2.useGravity = false; val2.mass = 0.4f; BoxCollider val3 = val.AddComponent<BoxCollider>(); val3.center = new Vector3(0f, 0.09f, -0.025f); val3.size = new Vector3(0.34f, 0.2f, 0.37f); val.AddComponent<AudioSource>().playOnAwake = false; val.AddComponent<CaptainsHatMarker>(); MeshRenderer mainObjectRenderer = HatModel.Build(val.transform); Definition = ScriptableObject.CreateInstance<Item>(); ((Object)Definition).name = "RocketHatItem"; Definition.itemName = "Captain's hat"; Definition.itemId = 847291; Definition.spawnPrefab = val; Definition.creditsWorth = 100; Definition.weight = 1f; Definition.isScrap = false; Definition.twoHanded = (Definition.twoHandedAnimation = false); Definition.canBeGrabbedBeforeGameStart = true; Definition.disallowUtilitySlot = false; Definition.requiresBattery = false; Definition.highestSalePercentage = 0; Definition.syncGrabFunction = (Definition.syncDiscardFunction = true); Definition.grabAnim = (Definition.useAnim = (Definition.pocketAnim = (Definition.throwAnim = ""))); Definition.grabAnimationTime = 0f; Definition.toolTips = Array.Empty<string>(); Definition.spawnPositionTypes = new List<ItemGroup>(); Definition.meshVariants = Array.Empty<Mesh>(); Definition.materialVariants = Array.Empty<Material>(); Definition.clinkAudios = Array.Empty<AudioClip>(); Definition.positionOffset = new Vector3(0.02f, 0.025f, -0.04f); Definition.rotationOffset = new Vector3(-12f, 0f, -10f); Definition.restingRotation = Vector3.zero; Definition.verticalOffset = 0.015f; Definition.allowDroppingAheadOfPlayer = true; Definition.itemIcon = LoadIcon(); PhysicsProp val4 = val.AddComponent<PhysicsProp>(); ((GrabbableObject)val4).itemProperties = Definition; ((GrabbableObject)val4).grabbable = (((GrabbableObject)val4).grabbableToEnemies = true); ((GrabbableObject)val4).mainObjectRenderer = mainObjectRenderer; ((GrabbableObject)val4).propBody = val2; ((GrabbableObject)val4).propColliders = (Collider[])(object)new Collider[1] { (Collider)val3 }; ((GrabbableObject)val4).originalScale = Vector3.one; ((GrabbableObject)val4).useCooldown = 0.1f; assembly.GetType("LethalLib.Modules.Items").GetMethod("RegisterShopItem", new Type[2] { typeof(Item), typeof(int) }).Invoke(null, new object[2] { Definition, 100 }); } private static Sprite LoadIcon() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("CaptainsHat.icon.png"); byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num == 0) { throw new InvalidOperationException("Incomplete captain's hat icon resource."); } } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { throw new InvalidOperationException("Could not load captain's hat icon."); } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 256f); } } internal static class HatModel { internal static MeshRenderer Build(Transform root) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0276: 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_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: 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_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) Shader shader = Shader.Find("HDRP/Lit") ?? Shader.Find("HDRP/Unlit"); if (!Object.op_Implicit((Object)(object)shader)) { throw new InvalidOperationException("Captain's hat shader unavailable."); } Material val = Mat(new Color(0.53f, 0.49f, 0.38f), 0.12f); Material material = Mat(new Color(0.035f, 0.048f, 0.065f), 0.15f); Material material2 = Mat(new Color(0.035f, 0.028f, 0.021f), 0.3f); Material material3 = Mat(new Color(0.53f, 0.36f, 0.11f), 0.35f, 0.55f); Material material4 = Mat(new Color(0.34f, 0.31f, 0.23f), 0.12f); Surface("Worn canvas crown", HatGeometry.Crown(), root, val); Surface("Navy hat band", HatGeometry.Band(), root, material); Surface("Curved leather visor", HatGeometry.Visor(), root, material2); for (int i = 0; i < 48; i++) { float num = (float)i * MathF.PI * 2f / 48f; float num2 = (float)(i + 1) * MathF.PI * 2f / 48f; Join("Tarnished gold band piping", new Vector3(Mathf.Cos(num) * 0.125f, 0.056f, Mathf.Sin(num) * 0.11f), new Vector3(Mathf.Cos(num2) * 0.125f, 0.056f, Mathf.Sin(num2) * 0.11f), 0.0023f, material3, root); } for (int j = 0; j < 22; j++) { float num3 = MathF.PI * (1.12f + (float)j * 0.76f / 22f); float num4 = MathF.PI * (1.12f + (float)(j + 1) * 0.76f / 22f); Join("Gold chin strap", new Vector3(Mathf.Cos(num3) * 0.13f, 0.033f + Mathf.Sin(num3) * 0.006f, Mathf.Sin(num3) * 0.119f), new Vector3(Mathf.Cos(num4) * 0.13f, 0.033f + Mathf.Sin(num4) * 0.006f, Mathf.Sin(num4) * 0.119f), 0.0033f, material3, root); } Part("Left brass button", (PrimitiveType)0, new Vector3(-0.121f, 0.038f, -0.036f), new Vector3(0.012f, 0.012f, 0.012f), material3, root); Part("Right brass button", (PrimitiveType)0, new Vector3(0.121f, 0.038f, -0.036f), new Vector3(0.012f, 0.012f, 0.012f), material3, root); Join("Anchor shaft", new Vector3(0f, 0.093f, -0.127f), new Vector3(0f, 0.141f, -0.131f), 0.003f, material3, root); Join("Anchor crossbar", new Vector3(-0.017f, 0.127f, -0.132f), new Vector3(0.017f, 0.127f, -0.132f), 0.003f, material3, root); for (int k = 0; k < 16; k++) { float num5 = (float)k * MathF.PI * 2f / 16f; float num6 = (float)(k + 1) * MathF.PI * 2f / 16f; Join("Anchor eye", new Vector3(Mathf.Cos(num5) * 0.006f, 0.147f + Mathf.Sin(num5) * 0.006f, -0.127f), new Vector3(Mathf.Cos(num6) * 0.006f, 0.147f + Mathf.Sin(num6) * 0.006f, -0.127f), 0.0018f, material3, root); } Join("Anchor left arm", new Vector3(0f, 0.093f, -0.127f), new Vector3(-0.022f, 0.108f, -0.13f), 0.003f, material3, root); Join("Anchor right arm", new Vector3(0f, 0.093f, -0.127f), new Vector3(0.022f, 0.108f, -0.13f), 0.003f, material3, root); Join("Anchor left fluke", new Vector3(-0.022f, 0.108f, -0.13f), new Vector3(-0.02f, 0.117f, -0.13f), 0.003f, material3, root); Join("Anchor right fluke", new Vector3(0.022f, 0.108f, -0.13f), new Vector3(0.02f, 0.117f, -0.13f), 0.003f, material3, root); for (int l = 0; l < 6; l++) { float num7 = -0.073f + (float)l * 0.005f; Join("Old repair stitch", new Vector3(num7, 0.137f, -0.108f), new Vector3(num7 + 0.002f, 0.143f, -0.107f), 0.0008f, material4, root); } return Combine(root, val); Material Mat(Color color, float smoothness, float metal = 0f) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) Material val2 = new Material(shader); string[] array = new string[3] { "_BaseColor", "_Color", "_UnlitColor" }; foreach (string text in array) { if (val2.HasProperty(text)) { val2.SetColor(text, color); } } if (val2.HasProperty("_Metallic")) { val2.SetFloat("_Metallic", metal); } if (val2.HasProperty("_Smoothness")) { val2.SetFloat("_Smoothness", smoothness); } return val2; } } private static MeshRenderer Combine(Transform root, Material mainMaterial) { //IL_0044: 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) //IL_006c: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) Dictionary<Material, List<CombineInstance>> dictionary = new Dictionary<Material, List<CombineInstance>>(); MeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshRenderer>(true); MeshRenderer[] array = componentsInChildren; foreach (MeshRenderer val in array) { Material sharedMaterial = ((Renderer)val).sharedMaterial; if (!dictionary.TryGetValue(sharedMaterial, out var value)) { value = (dictionary[sharedMaterial] = new List<CombineInstance>()); } List<CombineInstance> list2 = value; CombineInstance item = default(CombineInstance); ((CombineInstance)(ref item)).mesh = ((Component)val).GetComponent<MeshFilter>().sharedMesh; ((CombineInstance)(ref item)).transform = root.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix; list2.Add(item); } MeshRenderer result = null; foreach (KeyValuePair<Material, List<CombineInstance>> item2 in dictionary) { Mesh val2 = new Mesh { name = "Captain's hat combined material" }; val2.CombineMeshes(item2.Value.ToArray(), true, true); val2.RecalculateBounds(); GameObject val3 = new GameObject("Captain's hat surface") { layer = ((Component)root).gameObject.layer }; val3.transform.SetParent(root, false); val3.AddComponent<MeshFilter>().sharedMesh = val2; MeshRenderer val4 = val3.AddComponent<MeshRenderer>(); ((Renderer)val4).sharedMaterial = item2.Key; if ((Object)(object)item2.Key == (Object)(object)mainMaterial) { result = val4; } } array = componentsInChildren; foreach (MeshRenderer obj in array) { ((Component)obj).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)obj).gameObject); } return result; } private static MeshRenderer Surface(string name, HatMeshData data, Transform parent, Material material) { //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_000d: Expected O, but got Unknown //IL_0050: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_00d8: 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) Mesh val = new Mesh { name = name }; Vector3[] array = (Vector3[])(object)new Vector3[data.Vertices.Count]; Vector2[] array2 = (Vector2[])(object)new Vector2[array.Length]; for (int i = 0; i < array.Length; i++) { HatVertex hatVertex = data.Vertices[i]; array[i] = new Vector3(hatVertex.X, hatVertex.Y, hatVertex.Z); array2[i] = new Vector2(hatVertex.X * 3f + 0.5f, hatVertex.Z * 3f + 0.5f); } val.vertices = array; val.uv = array2; val.triangles = data.Triangles.ToArray(); val.RecalculateNormals(); val.RecalculateBounds(); GameObject val2 = new GameObject(name) { layer = ((Component)parent).gameObject.layer }; val2.transform.SetParent(parent, false); val2.AddComponent<MeshFilter>().sharedMesh = val; MeshRenderer obj = val2.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterial = material; return obj; } private static void Part(string name, PrimitiveType type, Vector3 position, Vector3 scale, Material material, Transform parent) { //IL_0000: 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_003f: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive(type); ((Object)obj).name = name; obj.layer = ((Component)parent).gameObject.layer; obj.transform.SetParent(parent, false); obj.transform.localPosition = position; obj.transform.localScale = scale; Collider component = obj.GetComponent<Collider>(); component.enabled = false; Object.Destroy((Object)(object)component); ((Renderer)obj.GetComponent<MeshRenderer>()).sharedMaterial = material; } private static void Join(string name, Vector3 start, Vector3 end, float radius, Material material, Transform parent) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0056: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)obj).name = name; obj.layer = ((Component)parent).gameObject.layer; obj.transform.SetParent(parent, false); obj.transform.localPosition = (start + end) * 0.5f; obj.transform.localRotation = Quaternion.FromToRotation(Vector3.up, end - start); Transform transform = obj.transform; float num = radius * 2f; Vector3 val = end - start; transform.localScale = new Vector3(num, ((Vector3)(ref val)).magnitude * 0.5f, radius * 2f); Collider component = obj.GetComponent<Collider>(); component.enabled = false; Object.Destroy((Object)(object)component); ((Renderer)obj.GetComponent<MeshRenderer>()).sharedMaterial = material; } } [HarmonyPatch] internal static class MaskedScanPatch { private static readonly FieldInfo KillAnimation = AccessTools.Field(typeof(MaskedPlayerEnemy), "inKillAnimation"); private static readonly FieldInfo Stare = AccessTools.Field(typeof(MaskedPlayerEnemy), "stareAtTransform"); private static readonly FieldInfo Lost = AccessTools.Field(typeof(MaskedPlayerEnemy), "lostPlayerInChase"); private static readonly FieldInfo LostTimer = AccessTools.Field(typeof(MaskedPlayerEnemy), "lostLOSTimer"); private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.DeclaredMethod(typeof(MaskedPlayerEnemy), "Update", (Type[])null, (Type[])null); yield return AccessTools.DeclaredMethod(typeof(MaskedPlayerEnemy), "DoAIInterval", (Type[])null, (Type[])null); } private static bool VisibleControlled(PlayerControllerB player) { if (player.isPlayerControlled) { return !Plugin.IsProtected(player); } return false; } private static bool Unavailable(PlayerControllerB player) { if (!player.isPlayerDead) { return Plugin.IsProtected(player); } return true; } [HarmonyTranspiler] internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { FieldInfo controlled = AccessTools.Field(typeof(PlayerControllerB), "isPlayerControlled"); FieldInfo dead = AccessTools.Field(typeof(PlayerControllerB), "isPlayerDead"); MethodInfo visible = AccessTools.Method(typeof(MaskedScanPatch), "VisibleControlled", (Type[])null, (Type[])null); MethodInfo unavailable = AccessTools.Method(typeof(MaskedScanPatch), "Unavailable", (Type[])null, (Type[])null); foreach (CodeInstruction instruction in instructions) { if (instruction.opcode == OpCodes.Ldfld && object.Equals(instruction.operand, controlled)) { CodeInstruction val = new CodeInstruction(instruction); val.opcode = OpCodes.Call; val.operand = visible; yield return val; } else if (instruction.opcode == OpCodes.Ldfld && object.Equals(instruction.operand, dead)) { CodeInstruction val2 = new CodeInstruction(instruction); val2.opcode = OpCodes.Call; val2.operand = unavailable; yield return val2; } else { yield return instruction; } } } [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(MaskedPlayerEnemy __instance) { ReleaseProtectedTarget(__instance); } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(MaskedPlayerEnemy __instance) { ReleaseProtectedTarget(__instance); } private static void ReleaseProtectedTarget(MaskedPlayerEnemy enemy) { if (!Object.op_Implicit((Object)(object)enemy) || !((NetworkBehaviour)enemy).IsOwner || ((EnemyAI)enemy).isEnemyDead || ((EnemyAI)enemy).inSpecialAnimation) { return; } object obj = KillAnimation?.GetValue(enemy); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) == 0 && Plugin.IsProtected(((EnemyAI)enemy).targetPlayer)) { ((EnemyAI)enemy).targetPlayer = null; ((EnemyAI)enemy).movingTowardsTargetPlayer = false; ((EnemyAI)enemy).moveTowardsDestination = false; Lost?.SetValue(enemy, false); LostTimer?.SetValue(enemy, 0f); Stare?.SetValue(enemy, null); if (Object.op_Implicit((Object)(object)((EnemyAI)enemy).agent) && ((Behaviour)((EnemyAI)enemy).agent).enabled && ((EnemyAI)enemy).agent.isOnNavMesh) { ((EnemyAI)enemy).agent.ResetPath(); } if (((EnemyAI)enemy).currentBehaviourStateIndex == 1) { ((EnemyAI)enemy).SwitchToBehaviourState(0); } } } } [BepInPlugin("achachala.rocketbeer", "Captain's Hat", "0.2.1")] [BepInDependency("evaisa.lethallib", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Id = "achachala.rocketbeer"; public const string Version = "0.2.1"; public const string SanctuaryId = "achachala.terminalsanctuary"; internal static Plugin Instance; private Harmony harmony; private bool soundsReady; private float nextSetup; private readonly Dictionary<ulong, string> observedProtection = new Dictionary<ulong, string>(); private ConfigEntry<bool> showIndicator; private ConfigEntry<float> indicatorX; private ConfigEntry<float> indicatorY; private ConfigEntry<float> indicatorScale; private GUIStyle? indicatorStyle; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown Instance = this; HatItem.Register(); harmony = new Harmony("achachala.rocketbeer"); if (Chainloader.PluginInfos.TryGetValue("achachala.terminalsanctuary", out var value)) { Type type = ((object)value.Instance).GetType(); MethodInfo methodInfo = AccessTools.Method(type, "IsProtected", new Type[1] { typeof(PlayerControllerB) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "IsProtectedNoise", new Type[1] { typeof(Vector3) }, (Type[])null); if (methodInfo == null || methodInfo2 == null) { throw new InvalidOperationException("Installed TerminalSanctuary has incompatible protection methods. Expected 0.1.2 API."); } harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "AddBeerProtection", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "AddBeerNoiseProtection", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Using TerminalSanctuary's existing enemy patches and protection indicator."); } else { InitializeIndicator(); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Standalone sanctuary protection patches enabled."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Captain's Hat 0.2.1 loaded. Store price: 100 credits. Install on host AND all clients."); } private void Update() { if (Time.unscaledTime < nextSetup) { return; } nextSetup = Time.unscaledTime + 1f; if (!Object.op_Implicit((Object)(object)StartOfRound.Instance)) { soundsReady = false; observedProtection.Clear(); return; } LogProtectionChanges(); if (soundsReady) { return; } Item val = ((IEnumerable<Item>)StartOfRound.Instance.allItemsList.itemsList).FirstOrDefault((Func<Item, bool>)((Item item) => Object.op_Implicit((Object)(object)item) && (Object)(object)item != (Object)(object)HatItem.Definition && Object.op_Implicit((Object)(object)item.grabSFX) && Object.op_Implicit((Object)(object)item.dropSFX) && item.itemName.IndexOf("bottle", StringComparison.OrdinalIgnoreCase) >= 0)); if (!Object.op_Implicit((Object)(object)val)) { val = ((IEnumerable<Item>)StartOfRound.Instance.allItemsList.itemsList).FirstOrDefault((Func<Item, bool>)((Item item) => Object.op_Implicit((Object)(object)item) && (Object)(object)item != (Object)(object)HatItem.Definition && Object.op_Implicit((Object)(object)item.grabSFX) && Object.op_Implicit((Object)(object)item.dropSFX))); } if (Object.op_Implicit((Object)(object)val)) { HatItem.Definition.grabSFX = val.grabSFX; HatItem.Definition.dropSFX = val.dropSFX; HatItem.Definition.pocketSFX = val.pocketSFX; HatItem.Definition.grabAnim = val.grabAnim; HatItem.Definition.pocketAnim = val.pocketAnim; HatItem.Definition.throwAnim = val.throwAnim; soundsReady = true; } } internal static bool IsProtected(PlayerControllerB? player) { NetworkManager singleton = NetworkManager.Singleton; if (!Object.op_Implicit((Object)(object)singleton) || !singleton.IsListening || !Object.op_Implicit((Object)(object)player)) { return false; } return CarriedProtection.Applies(player.ItemSlots, player.ItemOnlySlot, !player.isPlayerDead, player.isPlayerControlled, (GrabbableObject slot) => Object.op_Implicit((Object)(object)slot) && Object.op_Implicit((Object)(object)((Component)slot).GetComponent<CaptainsHatMarker>())); } private void LogProtectionChanges() { NetworkManager singleton = NetworkManager.Singleton; if (!Object.op_Implicit((Object)(object)singleton) || !singleton.IsListening) { observedProtection.Clear(); return; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!Object.op_Implicit((Object)(object)val)) { continue; } string text = "inactive"; if (IsProtected(val)) { if (Object.op_Implicit((Object)(object)val.ItemOnlySlot) && Object.op_Implicit((Object)(object)((Component)val.ItemOnlySlot).GetComponent<CaptainsHatMarker>())) { text = "utility slot"; } else { int num = 0; while (val.ItemSlots != null && num < val.ItemSlots.Length) { if (Object.op_Implicit((Object)(object)val.ItemSlots[num]) && Object.op_Implicit((Object)(object)((Component)val.ItemSlots[num]).GetComponent<CaptainsHatMarker>())) { text = $"inventory slot {num + 1}"; break; } num++; } } } observedProtection.TryGetValue(val.actualClientId, out string value); if (value != text && (text != "inactive" || (value != null && value != "inactive"))) { ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Captain's hat protection {0} for client {1}: {2}.", (text == "inactive") ? "OFF" : "ON", val.actualClientId, text)); } observedProtection[val.actualClientId] = text; } } internal static bool IsProtectedNoise(Vector3 position) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) if (!Object.op_Implicit((Object)(object)StartOfRound.Instance)) { return false; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (IsProtected(val)) { Vector3 val2 = ((Component)val).transform.position - position; if (((Vector3)(ref val2)).sqrMagnitude <= 4f) { return true; } } } return false; } private static void AddBeerProtection(PlayerControllerB __0, ref bool __result) { if (IsProtected(__0)) { __result = true; } } private static void AddBeerNoiseProtection(Vector3 __0, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (IsProtectedNoise(__0)) { __result = true; } } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private void InitializeIndicator() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown showIndicator = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "ShowIndicator", true, "Local preference: show CAPTAIN'S HAT PROTECTED while your player has enemy concealment. This does not mean damage immunity."); indicatorX = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "IndicatorX", 0.5f, new ConfigDescription("Local preference: horizontal screen position (0=left, 0.5=center, 1=right). The badge stays on screen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); indicatorY = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "IndicatorY", 0.16f, new ConfigDescription("Local preference: vertical screen position (0=top, 1=bottom). Adjust if another HUD overlaps.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); indicatorScale = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "IndicatorScale", 1f, new ConfigDescription("Local preference: badge size multiplier, on top of automatic scaling for screen height.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 2f), Array.Empty<object>())); } private void OnGUI() { //IL_0207: 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) //IL_0020: Invalid comparison between Unknown and I4 //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) if (showIndicator == null || !showIndicator.Value || (int)Event.current.type != 7) { return; } GameNetworkManager instance = GameNetworkManager.Instance; if (!Object.op_Implicit((Object)(object)instance) || !IsProtected(instance.localPlayerController)) { return; } float num = Mathf.Clamp((float)Screen.height / 1080f, 0.65f, 2.5f) * indicatorScale.Value; float num2 = Mathf.Min(350f * num, (float)Screen.width - 16f); float num3 = 38f * num; float num4 = Mathf.Clamp((float)Screen.width * indicatorX.Value - num2 / 2f, 8f, (float)Screen.width - num2 - 8f); float num5 = Mathf.Clamp((float)Screen.height * indicatorY.Value, 8f, Mathf.Max(8f, (float)Screen.height - num3 - 8f)); Rect val = default(Rect); ((Rect)(ref val))..ctor(num4, num5, num2, num3); if (indicatorStyle == null) { indicatorStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontStyle = (FontStyle)1, wordWrap = false }; indicatorStyle.normal.textColor = new Color(0.48f, 1f, 0.68f, 1f); } indicatorStyle.fontSize = Mathf.RoundToInt(18f * num); Color color = GUI.color; int depth = GUI.depth; try { GUI.depth = -100; GUI.color = new Color(0.025f, 0.08f, 0.055f, 0.9f); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); GUI.color = new Color(0.35f, 0.95f, 0.55f, 1f); GUI.DrawTexture(new Rect(num4, num5, 3f * num, num3), (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; GUI.Label(val, "CAPTAIN'S HAT PROTECTED", indicatorStyle); } finally { GUI.color = color; GUI.depth = depth; } } } public sealed class CaptainsHatMarker : MonoBehaviour { } [HarmonyPatch] internal static class TargetablePatch { private static IEnumerable<MethodBase> TargetMethods() { return from m in (from t in typeof(EnemyAI).Assembly.GetTypes() where typeof(EnemyAI).IsAssignableFrom(t) select t).SelectMany((Type t) => t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) where m.Name == "PlayerIsTargetable" && !m.IsAbstract && m.ReturnType == typeof(bool) && m.GetParameters().Length != 0 && m.GetParameters()[0].ParameterType == typeof(PlayerControllerB) select m; } [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(PlayerControllerB __0, ref bool __result) { if (Plugin.IsProtected(__0)) { __result = false; } } } [HarmonyPatch] internal static class SightPatch { private static readonly HashSet<string> Names = new HashSet<string> { "GetClosestPlayer", "TargetClosestPlayer", "CheckLineOfSightForPlayer", "CheckLineOfSightForClosestPlayer", "GetAllPlayersInLineOfSight", "GetAllPlayersInLineOfSightNonAlloc" }; private static IEnumerable<MethodBase> TargetMethods() { return from m in typeof(EnemyAI).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where Names.Contains(m.Name) select m; } [HarmonyPrefix] [HarmonyPriority(800)] private static void Prefix(out List<PlayerControllerB> __state) { __state = new List<PlayerControllerB>(); if (!Object.op_Implicit((Object)(object)StartOfRound.Instance)) { return; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (Object.op_Implicit((Object)(object)val) && val.isPlayerControlled && Plugin.IsProtected(val)) { __state.Add(val); val.isPlayerControlled = false; } } } [HarmonyFinalizer] private static Exception? Finalizer(Exception? __exception, List<PlayerControllerB>? __state) { if (__state != null) { foreach (PlayerControllerB item in __state) { if (Object.op_Implicit((Object)(object)item)) { item.isPlayerControlled = true; } } } return __exception; } } [HarmonyPatch(typeof(EnemyAI), "MeetsStandardPlayerCollisionConditions")] internal static class CollisionPatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ref PlayerControllerB? __result) { if (Plugin.IsProtected(__result)) { __result = null; } } } [HarmonyPatch] internal static class NoisePatch { private static IEnumerable<MethodBase> TargetMethods() { return from m in (from t in typeof(EnemyAI).Assembly.GetTypes() where typeof(EnemyAI).IsAssignableFrom(t) select t).SelectMany((Type t) => t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) where m.Name == "DetectNoise" && !m.IsAbstract && m.GetParameters().Length != 0 && m.GetParameters()[0].ParameterType == typeof(Vector3) select m; } [HarmonyPrefix] private static bool Prefix(Vector3 __0) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return !Plugin.IsProtectedNoise(__0); } } }