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 HamudHabob v1.0.0
HamudHabob.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json.Linq; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [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 HamudHabob { public class GlbModel { public GameObject Root; public SkinnedMeshRenderer Renderer; public Texture2D Texture; public Texture2D Emission; public Color EmissionColor = Color.black; public Bounds MeshBounds; public readonly Dictionary<string, AnimationClip> Clips = new Dictionary<string, AnimationClip>(); } public static class GlbLoader { private class Ctx { public JObject Json; public byte[] Data; public int BinStart; } public static GlbModel Load(string path, Transform templateParent) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_05bf: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Expected O, but got Unknown //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_0506: Unknown result type (might be due to invalid IL or missing references) //IL_054b: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) byte[] array = File.ReadAllBytes(path); if (BitConverter.ToUInt32(array, 0) != 1179937895) { throw new InvalidDataException(path + " is not a .glb file"); } int num = BitConverter.ToInt32(array, 12); Ctx ctx = new Ctx { Json = JObject.Parse(Encoding.UTF8.GetString(array, 20, num)), Data = array, BinStart = 20 + num + 8 }; JObject json = ctx.Json; GlbModel glbModel = new GlbModel(); glbModel.Root = new GameObject(Path.GetFileNameWithoutExtension(path)); glbModel.Root.transform.SetParent(templateParent, false); JArray val = (JArray)json["nodes"]; Transform[] nodes = (Transform[])(object)new Transform[((JContainer)val).Count]; for (int i = 0; i < nodes.Length; i++) { GameObject val2 = new GameObject(((string)val[i][(object)"name"]) ?? ("node_" + i)); nodes[i] = val2.transform; } for (int j = 0; j < nodes.Length; j++) { JToken val3 = val[j]; JToken obj = val3[(object)"children"]; JArray val4 = (JArray)(object)((obj is JArray) ? obj : null); if (val4 != null) { foreach (JToken item in val4) { nodes[(int)item].SetParent(nodes[j], false); } } ApplyTrs(nodes[j], val3); } int valueOrDefault = ((int?)json["scene"]).GetValueOrDefault(); foreach (JToken item2 in (IEnumerable<JToken>)json["scenes"][(object)valueOrDefault][(object)"nodes"]) { nodes[(int)item2].SetParent(glbModel.Root.transform, false); } JToken obj2 = json["materials"]; JToken val5 = ((IEnumerable<JToken>)((obj2 is JArray) ? obj2 : null))?.FirstOrDefault(); object textureInfo; if (val5 == null) { textureInfo = null; } else { JToken obj3 = val5[(object)"pbrMetallicRoughness"]; textureInfo = ((obj3 != null) ? obj3[(object)"baseColorTexture"] : null); } int? num2 = ImageOf(json, (JToken)textureInfo); int? num3 = ImageOf(json, (val5 != null) ? val5[(object)"emissiveTexture"] : null); if (!num2.HasValue) { JToken obj4 = json["images"]; JArray val6 = (JArray)(object)((obj4 is JArray) ? obj4 : null); if (val6 != null && ((JContainer)val6).Count > 0) { num2 = 0; } } if (num2.HasValue) { glbModel.Texture = LoadImage(ctx, num2.Value, ((Object)glbModel.Root).name + "_texture"); } if (num3.HasValue) { glbModel.Emission = LoadImage(ctx, num3.Value, ((Object)glbModel.Root).name + "_emission"); object obj5; if (val5 == null) { obj5 = null; } else { JToken obj6 = val5[(object)"extensions"]; if (obj6 == null) { obj5 = null; } else { JToken obj7 = obj6[(object)"KHR_materials_emissive_strength"]; obj5 = ((obj7 != null) ? obj7[(object)"emissiveStrength"] : null); } } float num4 = ((float?)(JToken)obj5) ?? 1f; JToken obj8 = ((val5 != null) ? val5[(object)"emissiveFactor"] : null); JArray val7 = (JArray)(object)((obj8 is JArray) ? obj8 : null); glbModel.EmissionColor = (Color)((val7 != null) ? new Color((float)val7[0], (float)val7[1], (float)val7[2]) : Color.white) * num4; } for (int k = 0; k < nodes.Length; k++) { JToken val8 = val[k]; if (val8[(object)"mesh"] == null) { continue; } Mesh val9 = BuildMesh(ctx, json["meshes"][(object)(int)val8[(object)"mesh"]]); SkinnedMeshRenderer val10 = ((Component)nodes[k]).gameObject.AddComponent<SkinnedMeshRenderer>(); if (val8[(object)"skin"] != null) { JToken val11 = json["skins"][(object)(int)val8[(object)"skin"]]; Transform[] joints = ((IEnumerable<JToken>)(JArray)val11[(object)"joints"]).Select((JToken val14) => nodes[(int)val14]).ToArray(); int count; float[] array2 = ReadFloats(ctx, (int)val11[(object)"inverseBindMatrices"], out count); Matrix4x4[] array3 = (Matrix4x4[])(object)new Matrix4x4[joints.Length]; for (int num5 = 0; num5 < joints.Length; num5++) { Matrix4x4 m = default(Matrix4x4); for (int num6 = 0; num6 < 4; num6++) { for (int num7 = 0; num7 < 4; num7++) { ((Matrix4x4)(ref m))[num7, num6] = array2[num5 * 16 + num6 * 4 + num7]; } } array3[num5] = MirrorX(m); } val9.bindposes = array3; val10.bones = joints; val10.rootBone = joints.First((Transform t) => !joints.Contains(t.parent)); } val10.sharedMesh = val9; val10.updateWhenOffscreen = true; glbModel.Renderer = val10; glbModel.MeshBounds = val9.bounds; } JToken obj9 = json["animations"]; JArray val12 = (JArray)(object)((obj9 is JArray) ? obj9 : null); if (val12 != null) { foreach (JToken item3 in val12) { AnimationClip val13 = BuildClip(ctx, item3, nodes, glbModel.Root.transform); glbModel.Clips[((Object)val13).name] = val13; } } return glbModel; } private static int? ImageOf(JObject json, JToken textureInfo) { if (((textureInfo != null) ? textureInfo[(object)"index"] : null) == null) { return null; } JToken obj = json["textures"]; object obj2; if (obj == null) { obj2 = null; } else { JToken obj3 = obj[(object)(int)textureInfo[(object)"index"]]; obj2 = ((obj3 != null) ? obj3[(object)"source"] : null); } return (int?)(JToken)obj2; } private static Texture2D LoadImage(Ctx ctx, int image, string name) { //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_009d: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00b4: Expected O, but got Unknown JToken val = ctx.Json["bufferViews"][(object)(int)ctx.Json["images"][(object)image][(object)"bufferView"]]; int srcOffset = ctx.BinStart + ((int?)val[(object)"byteOffset"]).GetValueOrDefault(); int num = (int)val[(object)"byteLength"]; byte[] array = new byte[num]; Buffer.BlockCopy(ctx.Data, srcOffset, array, 0, num); Texture2D val2 = new Texture2D(2, 2, (TextureFormat)4, true); ImageConversion.LoadImage(val2, array); ((Object)val2).name = name; ((Texture)val2).wrapMode = (TextureWrapMode)1; ((Texture)val2).filterMode = (FilterMode)0; return val2; } private static Vector3 ConvPos(float x, float y, float z) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) return new Vector3(0f - x, y, z); } private static Quaternion ConvRot(float x, float y, float z, float w) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return new Quaternion(x, 0f - y, 0f - z, w); } private static Matrix4x4 MirrorX(Matrix4x4 m) { //IL_000f: 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) //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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Matrix4x4 val = Matrix4x4.Scale(new Vector3(-1f, 1f, 1f)); return val * m * val; } private static void ApplyTrs(Transform t, JToken n) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_0079: 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) //IL_0166: Unknown result type (might be due to invalid IL or missing references) JToken obj = n[(object)"matrix"]; JArray val = (JArray)(object)((obj is JArray) ? obj : null); if (val != null) { Matrix4x4 m = default(Matrix4x4); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { ((Matrix4x4)(ref m))[j, i] = (float)val[i * 4 + j]; } } m = MirrorX(m); t.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref m)).GetColumn(3)); t.localRotation = ((Matrix4x4)(ref m)).rotation; t.localScale = ((Matrix4x4)(ref m)).lossyScale; return; } JToken obj2 = n[(object)"translation"]; JArray val2 = (JArray)(object)((obj2 is JArray) ? obj2 : null); if (val2 != null) { t.localPosition = ConvPos((float)val2[0], (float)val2[1], (float)val2[2]); } JToken obj3 = n[(object)"rotation"]; JArray val3 = (JArray)(object)((obj3 is JArray) ? obj3 : null); if (val3 != null) { t.localRotation = ConvRot((float)val3[0], (float)val3[1], (float)val3[2], (float)val3[3]); } JToken obj4 = n[(object)"scale"]; JArray val4 = (JArray)(object)((obj4 is JArray) ? obj4 : null); if (val4 != null) { t.localScale = new Vector3((float)val4[0], (float)val4[1], (float)val4[2]); } } private static Mesh BuildMesh(Ctx ctx, JToken meshJson) { //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); List<Vector2> list3 = new List<Vector2>(); List<BoneWeight> list4 = new List<BoneWeight>(); List<int[]> list5 = new List<int[]>(); foreach (JToken item2 in (IEnumerable<JToken>)meshJson[(object)"primitives"]) { JToken val = item2[(object)"attributes"]; int count = list.Count; int count2; float[] array = ReadFloats(ctx, (int)val[(object)"POSITION"], out count2); for (int i = 0; i < count2; i++) { list.Add(ConvPos(array[i * 3], array[i * 3 + 1], array[i * 3 + 2])); } int count3; if (val[(object)"NORMAL"] != null) { float[] array2 = ReadFloats(ctx, (int)val[(object)"NORMAL"], out count3); for (int j = 0; j < count2; j++) { list2.Add(ConvPos(array2[j * 3], array2[j * 3 + 1], array2[j * 3 + 2])); } } if (val[(object)"TEXCOORD_0"] != null) { float[] array3 = ReadFloats(ctx, (int)val[(object)"TEXCOORD_0"], out count3); for (int k = 0; k < count2; k++) { list3.Add(new Vector2(array3[k * 2], 1f - array3[k * 2 + 1])); } } if (val[(object)"JOINTS_0"] != null && val[(object)"WEIGHTS_0"] != null) { int[] array4 = ReadInts(ctx, (int)val[(object)"JOINTS_0"]); float[] array5 = ReadFloats(ctx, (int)val[(object)"WEIGHTS_0"], out count3); for (int l = 0; l < count2; l++) { float num = array5[l * 4] + array5[l * 4 + 1] + array5[l * 4 + 2] + array5[l * 4 + 3]; if (num <= 0f) { num = 1f; } BoneWeight item = default(BoneWeight); ((BoneWeight)(ref item)).boneIndex0 = array4[l * 4]; ((BoneWeight)(ref item)).weight0 = array5[l * 4] / num; ((BoneWeight)(ref item)).boneIndex1 = array4[l * 4 + 1]; ((BoneWeight)(ref item)).weight1 = array5[l * 4 + 1] / num; ((BoneWeight)(ref item)).boneIndex2 = array4[l * 4 + 2]; ((BoneWeight)(ref item)).weight2 = array5[l * 4 + 2] / num; ((BoneWeight)(ref item)).boneIndex3 = array4[l * 4 + 3]; ((BoneWeight)(ref item)).weight3 = array5[l * 4 + 3] / num; list4.Add(item); } } int[] array6 = ((item2[(object)"indices"] != null) ? ReadInts(ctx, (int)item2[(object)"indices"]) : Enumerable.Range(0, count2).ToArray()); int[] array7 = new int[array6.Length]; for (int m = 0; m + 2 < array6.Length; m += 3) { array7[m] = array6[m] + count; array7[m + 1] = array6[m + 2] + count; array7[m + 2] = array6[m + 1] + count; } list5.Add(array7); } Mesh val2 = new Mesh { name = (((string)meshJson[(object)"name"]) ?? "glb_mesh") }; if (list.Count > 65535) { val2.indexFormat = (IndexFormat)1; } val2.SetVertices(list); if (list2.Count == list.Count) { val2.SetNormals(list2); } if (list3.Count == list.Count) { val2.SetUVs(0, list3); } if (list4.Count == list.Count) { val2.boneWeights = list4.ToArray(); } val2.subMeshCount = list5.Count; for (int n = 0; n < list5.Count; n++) { val2.SetTriangles(list5[n], n); } if (list2.Count != list.Count) { val2.RecalculateNormals(); } val2.RecalculateBounds(); return val2; } private static AnimationClip BuildClip(Ctx ctx, JToken anim, Transform[] nodes, Transform root) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: 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_01d5: 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_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: 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_0246: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: 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) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Expected O, but got Unknown //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) AnimationClip val = new AnimationClip { legacy = true, name = (((string)anim[(object)"name"]) ?? "anim") }; JArray val2 = (JArray)anim[(object)"samplers"]; foreach (JToken item in (IEnumerable<JToken>)anim[(object)"channels"]) { JToken val3 = item[(object)"target"]; if (val3[(object)"node"] == null) { continue; } string text = (string)val3[(object)"path"]; JToken val4 = val2[(int)item[(object)"sampler"]]; string text2 = ((string)val4[(object)"interpolation"]) ?? "LINEAR"; int count; float[] array = ReadFloats(ctx, (int)val4[(object)"input"], out count); int count2; float[] array2 = ReadFloats(ctx, (int)val4[(object)"output"], out count2); int num = ((text == "rotation") ? 4 : 3); if (text == "weights") { continue; } float[][] array3 = new float[count][]; Quaternion val5 = Quaternion.identity; for (int i = 0; i < count; i++) { int num2 = ((text2 == "CUBICSPLINE") ? ((i * 3 + 1) * num) : (i * num)); if (!(text == "translation")) { if (text == "rotation") { Quaternion val6 = ConvRot(array2[num2], array2[num2 + 1], array2[num2 + 2], array2[num2 + 3]); if (i > 0 && Quaternion.Dot(val5, val6) < 0f) { ((Quaternion)(ref val6))..ctor(0f - val6.x, 0f - val6.y, 0f - val6.z, 0f - val6.w); } val5 = val6; array3[i] = new float[4] { val6.x, val6.y, val6.z, val6.w }; } else { array3[i] = new float[3] { array2[num2], array2[num2 + 1], array2[num2 + 2] }; } } else { Vector3 val7 = ConvPos(array2[num2], array2[num2 + 1], array2[num2 + 2]); array3[i] = new float[3] { val7.x, val7.y, val7.z }; } } string text3 = ((text == "translation") ? "localPosition" : ((text == "rotation") ? "localRotation" : "localScale")); string[] array4 = new string[4] { "x", "y", "z", "w" }; string text4 = PathTo(nodes[(int)val3[(object)"node"]], root); for (int j = 0; j < num; j++) { Keyframe[] array5 = (Keyframe[])(object)new Keyframe[count]; for (int k = 0; k < count; k++) { float num3 = array3[k][j]; float num4 = 0f; float num5 = 0f; if (text2 == "STEP") { num4 = (num5 = float.PositiveInfinity); } else { if (k > 0) { num4 = (num3 - array3[k - 1][j]) / Mathf.Max(1E-05f, array[k] - array[k - 1]); } if (k < count - 1) { num5 = (array3[k + 1][j] - num3) / Mathf.Max(1E-05f, array[k + 1] - array[k]); } if (k == 0) { num4 = num5; } if (k == count - 1) { num5 = num4; } } array5[k] = new Keyframe(array[k], num3, num4, num5); } val.SetCurve(text4, typeof(Transform), text3 + "." + array4[j], new AnimationCurve(array5)); } } val.EnsureQuaternionContinuity(); return val; } private static string PathTo(Transform t, Transform root) { List<string> list = new List<string>(); Transform val = t; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list); } private static int ComponentCount(string type) { return type switch { "SCALAR" => 1, "VEC2" => 2, "VEC3" => 3, "VEC4" => 4, "MAT4" => 16, _ => throw new NotSupportedException("accessor type " + type), }; } private static float[] ReadFloats(Ctx ctx, int accessor, out int count) { JToken val = ctx.Json["accessors"][(object)accessor]; count = (int)val[(object)"count"]; int num = ComponentCount((string)val[(object)"type"]); int num2 = (int)val[(object)"componentType"]; bool valueOrDefault = (bool?)val[(object)"normalized"] == true; GetLayout(ctx, val, num2, num, out var start, out var stride); float[] array = new float[count * num]; int num3 = ComponentSize(num2); for (int i = 0; i < count; i++) { for (int j = 0; j < num; j++) { int num4 = start + i * stride + j * num3; float num5; switch (num2) { case 5126: num5 = BitConverter.ToSingle(ctx.Data, num4); break; case 5121: num5 = (int)ctx.Data[num4]; if (valueOrDefault) { num5 /= 255f; } break; case 5123: num5 = (int)BitConverter.ToUInt16(ctx.Data, num4); if (valueOrDefault) { num5 /= 65535f; } break; case 5120: num5 = (sbyte)ctx.Data[num4]; if (valueOrDefault) { num5 = Mathf.Max(num5 / 127f, -1f); } break; case 5122: num5 = BitConverter.ToInt16(ctx.Data, num4); if (valueOrDefault) { num5 = Mathf.Max(num5 / 32767f, -1f); } break; case 5125: num5 = BitConverter.ToUInt32(ctx.Data, num4); break; default: throw new NotSupportedException("componentType " + num2); } array[i * num + j] = num5; } } return array; } private static int[] ReadInts(Ctx ctx, int accessor) { JToken val = ctx.Json["accessors"][(object)accessor]; int num = (int)val[(object)"count"]; int num2 = ComponentCount((string)val[(object)"type"]); int num3 = (int)val[(object)"componentType"]; GetLayout(ctx, val, num3, num2, out var start, out var stride); int num4 = ComponentSize(num3); int[] array = new int[num * num2]; for (int i = 0; i < num; i++) { for (int j = 0; j < num2; j++) { int num5 = start + i * stride + j * num4; switch (num3) { case 5121: array[i * num2 + j] = ctx.Data[num5]; break; case 5123: array[i * num2 + j] = BitConverter.ToUInt16(ctx.Data, num5); break; case 5125: array[i * num2 + j] = (int)BitConverter.ToUInt32(ctx.Data, num5); break; default: throw new NotSupportedException("index componentType " + num3); } } } return array; } private static int ComponentSize(int ctype) { switch (ctype) { default: return 1; case 5122: case 5123: return 2; case 5125: case 5126: return 4; } } private static void GetLayout(Ctx ctx, JToken a, int ctype, int n, out int start, out int stride) { JToken val = ctx.Json["bufferViews"][(object)(int)a[(object)"bufferView"]]; start = ctx.BinStart + ((int?)val[(object)"byteOffset"]).GetValueOrDefault() + ((int?)a[(object)"byteOffset"]).GetValueOrDefault(); stride = ((int?)val[(object)"byteStride"]) ?? (ComponentSize(ctype) * n); } } public static class HamudSounds { internal static AudioClip[] Voices = (AudioClip[])(object)new AudioClip[0]; internal static AudioClip[] Laughs = (AudioClip[])(object)new AudioClip[0]; internal static AudioClip[] Pop = (AudioClip[])(object)new AudioClip[0]; internal static void Load(string dir) { Voices = LoadAll("hamud_voice"); Laughs = LoadAll("hamud_laugh"); Pop = LoadAll("hamud_pop"); Plugin.Log.LogInfo((object)($"Sounds: {Voices.Length} voice, {Laughs.Length} laugh, {Pop.Length} pop " + "[" + string.Join(", ", from c in Voices.Concat(Laughs).Concat(Pop) select $"{((Object)c).name} {c.length:0.00}s") + "]")); AudioClip[] LoadAll(string prefix) { return (from f in Directory.GetFiles(dir, prefix + "*.wav") orderby f select f).Select(delegate(string f) { AudioClip obj = WavLoader.Load(f); ((Object)obj).name = Path.GetFileNameWithoutExtension(f); return obj; }).ToArray(); } } internal static GameObject MakeSfx(string name, GameObject template, AudioClip[] clips, string caption, bool throttle = true) { if (clips.Length == 0) { return null; } GameObject val = PrefabManager.Instance.CreateClonedPrefab(name, template); ZSFX component = val.GetComponent<ZSFX>(); component.m_audioClips = clips; component.m_minPitch = 0.97f; component.m_maxPitch = 1.03f; component.m_minVol = (component.m_maxVol = Plugin.VoiceVolume.Value); component.m_closedCaptionToken = caption; component.m_secondaryCaptionToken = ""; component.m_maxConcurrentSources = 0; if (throttle) { val.AddComponent<HamudVoiceThrottle>(); } ZNetView[] componentsInChildren = val.GetComponentsInChildren<ZNetView>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } TimedDestruction obj = val.GetComponent<TimedDestruction>() ?? val.AddComponent<TimedDestruction>(); obj.m_timeout = clips.Max((AudioClip c) => c.length) + 1f; obj.m_triggerOnAwake = true; AudioSource component2 = val.GetComponent<AudioSource>(); if ((Object)(object)component2 != (Object)null) { component2.loop = false; component2.maxDistance = Mathf.Max(component2.maxDistance, 35f); } return val; } internal static void Play(GameObject sfx, Vector3 pos) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)sfx != (Object)null) { Object.Instantiate<GameObject>(sfx, pos, Quaternion.identity); } } } public class HamudVoiceThrottle : MonoBehaviour { private const float Radius = 10f; private static readonly List<HamudVoiceThrottle> s_active = new List<HamudVoiceThrottle>(); private float m_until; private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) s_active.RemoveAll((HamudVoiceThrottle s) => (Object)(object)s == (Object)null || Time.time >= s.m_until); Vector3 pos = ((Component)this).transform.position; if (s_active.Any(delegate(HamudVoiceThrottle s) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //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_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)s).transform.position - pos; return ((Vector3)(ref val)).sqrMagnitude < 100f; })) { ((Component)this).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)this).gameObject); return; } float num = 2f; ((Component)this).GetComponent<AudioSource>(); ZSFX component = ((Component)this).GetComponent<ZSFX>(); if ((Object)(object)component != (Object)null && component.m_audioClips.Length != 0) { num = component.m_audioClips.Max((AudioClip c) => c.length); } m_until = Time.time + num + 0.3f; s_active.Add(this); } private void OnDestroy() { s_active.Remove(this); } } public class HamudThief : MonoBehaviour { internal const string ZLoot = "hamud_loot"; internal const string ZLootCount = "hamud_lootcount"; internal const string ZHeld = "hamud_held"; internal const string ZFleeUntil = "hamud_flee_until"; internal const string ZLaughs = "hamud_laughs"; internal const string ZVictim = "hamud_victim"; internal const string ZStealable = "hamud_stealable"; internal const string ZSnatches = "hamud_snatches"; private const string RpcLoot = "Hamud_Loot"; private const string RpcSnatch = "Hamud_Snatch"; private const float SnatchCooldown = 1.2f; private const float FullSackFleeRange = 16f; private const float GiveUpRange = 45f; private ZNetView m_nview; private Character m_character; private MonsterAI m_ai; private bool m_aiFleeing; private float m_nextIdleLaugh; private float m_nextSnatch; private float m_nextNotice; private float m_nextNoticeDebug; private static readonly bool s_debug = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SAHUR_TEST_OUT")); private static float s_nextFlagUpdate; private static int s_sightMask; private ZDO Zdo { get { if (!((Object)(object)m_nview != (Object)null) || !m_nview.IsValid()) { return null; } return m_nview.GetZDO(); } } internal int LootCount { get { ZDO zdo = Zdo; if (zdo == null) { return 0; } return zdo.GetInt("hamud_lootcount", 0); } } internal string LootString { get { ZDO zdo = Zdo; return ((zdo != null) ? zdo.GetString("hamud_loot", "") : null) ?? ""; } } internal static double Now { get { if (!((Object)(object)ZNet.instance != (Object)null)) { return Time.time; } return ZNet.instance.GetTimeSeconds(); } } internal bool IsFleeing { get { if (Zdo != null) { return Now < (double)Zdo.GetFloat("hamud_flee_until", 0f); } return false; } } internal bool CanSteal { get { if (Zdo != null && !m_character.IsDead()) { return LootCount < Plugin.MaxLoot.Value; } return false; } } private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); m_character = ((Component)this).GetComponent<Character>(); m_ai = ((Component)this).GetComponent<MonsterAI>(); if ((Object)(object)m_nview != (Object)null && m_nview.IsValid()) { m_nview.Register<ZPackage, ZDOID>("Hamud_Loot", (Action<long, ZPackage, ZDOID>)RPC_Loot); m_nview.Register<ZDOID>("Hamud_Snatch", (Action<long, ZDOID>)RPC_Snatch); } m_nextIdleLaugh = Time.time + Random.Range(8f, 16f); } internal static List<ItemData> Stealables(Inventory inv) { return (from i in inv.GetAllItems() where (Object)(object)i.m_dropPrefab != (Object)null && (Plugin.StealEquipped.Value || !i.m_equipped) && (Plugin.StealFromHotbar.Value || i.m_gridPos.y > 0) select i).ToList(); } internal static void UpdateStealableFlag(Player player) { if (!(Time.time < s_nextFlagUpdate) && !((Object)(object)((Character)player).m_nview == (Object)null) && ((Character)player).m_nview.IsValid() && ((Character)player).m_nview.IsOwner()) { s_nextFlagUpdate = Time.time + 1f; bool flag = Stealables(((Humanoid)player).GetInventory()).Count > 0; ZDO zDO = ((Character)player).m_nview.GetZDO(); if (zDO.GetBool("hamud_stealable", true) != flag) { zDO.Set("hamud_stealable", flag); } } } internal bool WantsTarget(Character other) { Player val = (Player)(object)((other is Player) ? other : null); if (val == null) { return false; } if (IsFleeing || LootCount >= Plugin.MaxLoot.Value) { return true; } ZNetView nview = ((Character)val).m_nview; if (!((Object)(object)nview == (Object)null) && nview.IsValid()) { return nview.GetZDO().GetBool("hamud_stealable", true); } return true; } internal static Inventory ParseLoot(string data) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown Inventory val = new Inventory("HamudLoot", (Sprite)null, 8, 4); if (!string.IsNullOrEmpty(data)) { val.Load(new ZPackage(data)); } return val; } internal static void StealFrom(Player victim, HamudThief thief) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0079: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = ((Humanoid)victim).GetInventory(); List<ItemData> list = Stealables(inventory); if (list.Count == 0) { Debug(victim.GetPlayerName() + " has nothing to steal"); return; } ItemData val = list[Random.Range(0, list.Count)]; if (val.m_equipped) { ((Humanoid)victim).UnequipItem(val, true); } ItemData val2 = val.Clone(); val2.m_equipped = false; Inventory val3 = new Inventory("HamudSwag", (Sprite)null, 1, 1); val3.AddItem(val2); ZPackage val4 = new ZPackage(); val3.Save(val4); inventory.RemoveItem(val); thief.m_nview.InvokeRPC("Hamud_Loot", new object[2] { val4, ((Character)victim).GetZDOID() }); string arg = Localization.instance.Localize(val.m_shared.m_name); MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, string.Format(Localization.instance.Localize("$hamud_stole"), arg, val.m_stack), 0, (Sprite)null, false, true); } Debug($"STOLE {((Object)val.m_dropPrefab).name} x{val.m_stack} from {victim.GetPlayerName()}"); } private void RPC_Snatch(long sender, ZDOID victim) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0082: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).GetZDOID() != victim || ((Character)localPlayer).IsDead() || !CanSteal) { return; } if (((Character)localPlayer).IsDodgeInvincible()) { Debug("snatch dodged"); return; } Vector3 val = Vector3.ProjectOnPlane(((Component)this).transform.position - ((Component)localPlayer).transform.position, Vector3.up); Vector3 normalized = ((Vector3)(ref val)).normalized; if (((Character)localPlayer).IsBlocking() && Vector3.Dot(((Component)localPlayer).transform.forward, normalized) > 0.5f) { Debug("snatch blocked"); } else { StealFrom(localPlayer, this); } } private void TrySnatch() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) if (Time.time < m_nextSnatch || !CanSteal) { return; } Character targetCreature = ((BaseAI)m_ai).GetTargetCreature(); Player val = (Player)(object)((targetCreature is Player) ? targetCreature : null); if (val == null || ((Character)val).IsDead() || !WantsTarget((Character)(object)val)) { return; } Vector3 val2 = ((Component)val).transform.position - ((Component)this).transform.position; if (!(Mathf.Abs(val2.y) > 1.5f)) { val2.y = 0f; if (!(((Vector3)(ref val2)).magnitude > Plugin.SnatchRange.Value)) { m_nextSnatch = Time.time + 1.2f; Zdo.Set("hamud_snatches", Zdo.GetInt("hamud_snatches", 0) + 1); m_nview.InvokeRPC(ZNetView.Everybody, "Hamud_Snatch", new object[1] { ((Character)val).GetZDOID() }); object arg = ((Vector3)(ref val2)).magnitude; Vector3 velocity = ((Character)val).GetVelocity(); Debug($"snatch at {arg:0.0}m (target speed {((Vector3)(ref velocity)).magnitude:0.0})"); } } } private void NoticeMarks() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) if (Time.time < m_nextNotice || (Object)(object)((BaseAI)m_ai).GetTargetCreature() != (Object)null) { return; } m_nextNotice = Time.time + 0.5f; Player val = null; float num = Plugin.NoticeRange.Value; foreach (Player allPlayer in Player.GetAllPlayers()) { if (!((Object)(object)allPlayer == (Object)null) && !((Character)allPlayer).IsDead() && !((Character)allPlayer).InGhostMode() && !((Character)allPlayer).IsDebugFlying() && WantsTarget((Character)(object)allPlayer)) { float num2 = Vector3.Distance(((Component)allPlayer).transform.position, ((Component)this).transform.position); if (s_debug && Time.time > m_nextNoticeDebug) { m_nextNoticeDebug = Time.time + 5f; object[] obj = new object[5] { num2, HasLineOfSight(allPlayer), Plugin.NoticeRange.Value, null, null }; Character targetCreature = ((BaseAI)m_ai).GetTargetCreature(); obj[3] = ((targetCreature != null) ? ((Object)targetCreature).name : null); obj[4] = ((BaseAI)m_ai).IsAlerted(); Debug(string.Format("notice check: {0:0}m los={1} range={2} target={3} alerted={4}", obj)); } if (num2 < num && (num2 < 8f || HasLineOfSight(allPlayer))) { val = allPlayer; num = num2; } } } if (!((Object)(object)val == (Object)null)) { m_ai.m_targetCreature = (Character)(object)val; ((BaseAI)m_ai).SetAlerted(true); Debug($"noticed {val.GetPlayerName()} at {num:0.0}m"); } } private bool HasLineOfSight(Player p) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (s_sightMask == 0) { s_sightMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "terrain", "piece", "viewblock" }); } Vector3 eyePoint = m_character.GetEyePoint(); Vector3 eyePoint2 = ((Character)p).GetEyePoint(); return !Physics.Linecast(eyePoint, eyePoint2, s_sightMask, (QueryTriggerInteraction)1); } private void RPC_Loot(long sender, ZPackage pkg, ZDOID victim) { //IL_0022: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (!m_nview.IsOwner()) { return; } Inventory val = ParseLoot(LootString); Inventory val2 = new Inventory("HamudSwag", (Sprite)null, 1, 1); val2.Load(pkg); string text = ""; foreach (ItemData item in val2.GetAllItems().ToList()) { item.m_equipped = false; text = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : text); if (!val.AddItem(item)) { ItemDrop.DropItem(item, item.m_stack, ((Component)this).transform.position + Vector3.up, Quaternion.identity); } } SaveLoot(val); ZDO zdo = Zdo; zdo.Set("hamud_held", text); zdo.Set("hamud_victim", victim); zdo.Set("hamud_flee_until", (float)(Now + (double)Plugin.FleeSeconds.Value)); zdo.Set("hamud_laughs", zdo.GetInt("hamud_laughs", 0) + 1); Debug(string.Format("loot now {0} stacks [{1}], fleeing for {2}s", LootCount, string.Join(", ", val.GetAllItems().Select(delegate(ItemData i) { GameObject dropPrefab = i.m_dropPrefab; return ((dropPrefab != null) ? ((Object)dropPrefab).name : null) + " x" + i.m_stack; })), Plugin.FleeSeconds.Value)); } private void SaveLoot(Inventory loot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); loot.Save(val); Zdo.Set("hamud_loot", val.GetBase64()); Zdo.Set("hamud_lootcount", loot.GetAllItems().Count); } private void Update() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0114: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid() || !m_nview.IsOwner() || (Object)(object)m_ai == (Object)null || m_character.IsDead()) { return; } Character val = null; bool flag = IsFleeing; if (flag) { ZDOID zDOID = Zdo.GetZDOID("hamud_victim"); GameObject val2 = (((ZDOID)(ref zDOID)).IsNone() ? null : ZNetScene.instance.FindInstance(zDOID)); val = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<Character>() : null); if ((Object)(object)val == (Object)null || val.IsDead()) { val = (Character)(object)Player.GetClosestPlayer(((Component)this).transform.position, 45f); } if ((Object)(object)val == (Object)null || Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) > 45f) { Zdo.Set("hamud_flee_until", 0f); flag = false; val = null; } } else if (LootCount >= Plugin.MaxLoot.Value) { val = (Character)(object)Player.GetClosestPlayer(((Component)this).transform.position, 16f); flag = (Object)(object)val != (Object)null; } if (flag) { m_ai.m_fleeIfLowHealth = 10f; m_ai.m_fleeTimeSinceHurt = 1E+09f; ((BaseAI)m_ai).m_timeSinceHurt = 0f; m_ai.m_targetCreature = val; ((BaseAI)m_ai).SetAlerted(true); m_aiFleeing = true; } else if (m_aiFleeing) { m_ai.m_fleeIfLowHealth = 0f; m_ai.m_fleeTimeSinceHurt = 20f; m_aiFleeing = false; Zdo.Set("hamud_laughs", Zdo.GetInt("hamud_laughs", 0) + 1); } if (!flag) { NoticeMarks(); TrySnatch(); } if (LootCount > 0 && !flag && Time.time > m_nextIdleLaugh) { m_nextIdleLaugh = Time.time + Random.Range(10f, 20f); if (Random.value < 0.35f) { Zdo.Set("hamud_laughs", Zdo.GetInt("hamud_laughs", 0) + 1); } } } internal static void Debug(string msg) { if (s_debug) { Plugin.Log.LogInfo((object)("[HamudThief] " + msg)); } } } public class HamudVisual : MonoBehaviour { public const string ModelName = "HamudModel"; internal static readonly HashSet<string> LoopingClips = new HashSet<string> { "idle", "sneak", "run", "flee", "laugh" }; private const float RunThreshold = 2.6f; private const float LaughShowSeconds = 1.6f; private Character m_character; private ZNetView m_nview; private Transform m_model; private Transform m_sack; private Transform m_hand; private Animation m_anim; private Animator m_baseAnimator; private Vector3 m_lastPos; private float m_speed; private bool m_wasAttacking; private float m_nextHideCheck; private int m_seenLaughs = -1; private int m_seenSnatches = -1; private float m_snatchUntil; private const float SnatchSeconds = 0.4f; private float m_laughUntil; private string m_heldName = ""; private GameObject m_held; private float m_sackScale = 1f; private static readonly int s_attackTag = Animator.StringToHash("attack"); private void Awake() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) m_character = ((Component)this).GetComponent<Character>(); m_nview = ((Component)this).GetComponent<ZNetView>(); m_model = ((Component)this).transform.Find("HamudModel"); m_anim = ((Component)m_model).GetComponent<Animation>(); m_sack = FindBone("Sack"); m_hand = FindBone("Hand.R"); m_baseAnimator = ((IEnumerable<Animator>)((Component)this).GetComponentsInChildren<Animator>(true)).FirstOrDefault((Func<Animator, bool>)((Animator a) => !((Component)a).transform.IsChildOf(m_model))); Animator[] componentsInChildren = ((Component)this).GetComponentsInChildren<Animator>(true); for (int num = 0; num < componentsInChildren.Length; num++) { componentsInChildren[num].cullingMode = (AnimatorCullingMode)0; } HideVanillaRenderers(((Component)this).gameObject, m_model); m_lastPos = ((Component)this).transform.position; m_anim.Play("idle"); } private Transform FindBone(string name) { return ((IEnumerable<Transform>)((Component)m_model).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == name)); } internal static void HideVanillaRenderers(GameObject root, Transform keep) { Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)keep == (Object)null || !((Component)val).transform.IsChildOf(keep)) { val.forceRenderingOff = true; } } Light[] componentsInChildren2 = root.GetComponentsInChildren<Light>(true); foreach (Light val2 in componentsInChildren2) { if ((Object)(object)keep == (Object)null || !((Component)val2).transform.IsChildOf(keep)) { ((Behaviour)val2).enabled = false; } } } private bool BaseAttacking(out float length) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) length = 1f; if ((Object)(object)m_baseAnimator != (Object)null) { AnimatorStateInfo val = (m_baseAnimator.IsInTransition(0) ? m_baseAnimator.GetNextAnimatorStateInfo(0) : m_baseAnimator.GetCurrentAnimatorStateInfo(0)); if (((AnimatorStateInfo)(ref val)).tagHash == s_attackTag) { length = Mathf.Max(0.3f, ((AnimatorStateInfo)(ref val)).length); return true; } } if ((Object)(object)m_character != (Object)null) { return m_character.InAttack(); } return false; } private void Update() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) float deltaTime = Time.deltaTime; if (deltaTime <= 0f || (Object)(object)m_character == (Object)null) { return; } if (Time.time >= m_nextHideCheck) { HideVanillaRenderers(((Component)this).gameObject, m_model); m_nextHideCheck = Time.time + 0.5f; } Vector3 val = ((Component)this).transform.position - m_lastPos; val.y = 0f; m_lastPos = ((Component)this).transform.position; m_speed = Mathf.Lerp(m_speed, ((Vector3)(ref val)).magnitude / deltaTime, 1f - Mathf.Exp((0f - deltaTime) * 8f)); ZDO val2 = (((Object)(object)m_nview != (Object)null && m_nview.IsValid()) ? m_nview.GetZDO() : null); int num = ((val2 != null) ? val2.GetInt("hamud_lootcount", 0) : 0); bool flag = val2 != null && HamudThief.Now < (double)val2.GetFloat("hamud_flee_until", 0f); int num2 = ((val2 != null) ? val2.GetInt("hamud_laughs", 0) : 0); if (m_seenLaughs < 0) { m_seenLaughs = num2; } if (num2 != m_seenLaughs) { m_seenLaughs = num2; m_laughUntil = Time.time + 1.6f; HamudSounds.Play((((num2 * -1640531535 >>> 16) & 1) == 0) ? Plugin.LaughSfx : Plugin.VoiceSfx, ((Component)this).transform.position); } int num3 = ((val2 != null) ? val2.GetInt("hamud_snatches", 0) : 0); if (m_seenSnatches < 0) { m_seenSnatches = num3; } if (num3 != m_seenSnatches) { m_seenSnatches = num3; m_snatchUntil = Time.time + 0.4f; AnimationState obj = m_anim["steal"]; obj.speed = obj.length / 0.4f; m_anim.CrossFade("steal", 0.05f); obj.time = 0f; } UpdateHeld(((val2 != null) ? val2.GetString("hamud_held", "") : null) ?? ""); m_sackScale = Mathf.MoveTowards(m_sackScale, 1f + 0.1f * (float)Mathf.Min(num, 6), deltaTime * 0.8f); if (BaseAttacking(out var length)) { if (!m_wasAttacking) { AnimationState obj2 = m_anim["steal"]; obj2.speed = obj2.length / length; m_anim.CrossFade("steal", 0.08f); obj2.time = 0f; Player localPlayer = Player.m_localPlayer; HamudThief.Debug($"swing ({length:0.00}s) dist to player {(((Object)(object)localPlayer != (Object)null) ? Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) : (-1f)):0.0}"); } m_wasAttacking = true; if ((Object)(object)m_held != (Object)null) { m_held.SetActive(false); } return; } m_wasAttacking = false; if (Time.time < m_snatchUntil) { if ((Object)(object)m_held != (Object)null) { m_held.SetActive(false); } return; } float speed = 1f; float num4 = Mathf.Max(0.01f, m_model.localScale.y); string text; if (m_speed < 0.25f) { text = ((Time.time < m_laughUntil) ? "laugh" : "idle"); } else if (m_speed < 2.6f) { text = "sneak"; speed = Mathf.Clamp(m_speed / (Plugin.WalkStride.Value * num4), 0.5f, 2f); } else { text = ((flag && m_heldName.Length > 0) ? "flee" : "run"); speed = Mathf.Clamp(m_speed / (Plugin.RunStride.Value * num4), 0.6f, 2.2f); } if ((Object)(object)m_held != (Object)null) { m_held.SetActive(text == "flee"); } m_anim[text].speed = speed; if (!m_anim.IsPlaying(text)) { m_anim.CrossFade(text, 0.15f); } } private void LateUpdate() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_sack != (Object)null && m_sackScale != 1f) { Transform sack = m_sack; sack.localScale *= m_sackScale; } } private void UpdateHeld(string name) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (name == m_heldName) { return; } m_heldName = name; if ((Object)(object)m_held != (Object)null) { Object.Destroy((Object)(object)m_held); } m_held = null; if (name.Length == 0 || (Object)(object)m_hand == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(name); if (!((Object)(object)itemPrefab == (Object)null)) { m_held = MakeProp(itemPrefab, m_hand); if ((Object)(object)m_held != (Object)null) { m_held.transform.localPosition = new Vector3(0f, 0.06f, 0f); m_held.SetActive(false); } } } internal static GameObject MakeProp(GameObject itemPrefab, Transform parent) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) Transform val = itemPrefab.transform.Find("attach") ?? itemPrefab.transform; ZNetView.m_forceDisableInit = true; GameObject val2; try { val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, parent, false); } finally { ZNetView.m_forceDisableInit = false; } ((Object)val2).name = "HamudHeld_" + ((Object)itemPrefab).name; Collider[] componentsInChildren = val2.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } Rigidbody[] componentsInChildren2 = val2.GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody obj in componentsInChildren2) { obj.isKinematic = true; obj.detectCollisions = false; } MonoBehaviour[] componentsInChildren3 = val2.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour obj2 in componentsInChildren3) { ((Behaviour)obj2).enabled = false; Object.Destroy((Object)(object)obj2); } componentsInChildren2 = val2.GetComponentsInChildren<Rigidbody>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.Destroy((Object)(object)componentsInChildren2[i]); } val2.transform.localRotation = Quaternion.identity; Vector3 lossyScale = parent.lossyScale; Vector3 val3 = val.localScale * 0.9f; val2.transform.localScale = new Vector3(val3.x / lossyScale.x, val3.y / lossyScale.y, val3.z / lossyScale.z); return val2; } } public class HamudCorpse : MonoBehaviour { internal const float BurstDelay = 1.2f; internal static string s_pendingLoot; internal static int s_pendingLevel = 1; private const string ZBurst = "hamud_burst"; private const string ZLevel = "hamud_level"; private ZNetView m_nview; private Transform m_model; private Transform m_sack; private float m_start; private bool m_burst; private void Awake() { m_nview = ((Component)this).GetComponent<ZNetView>(); if (s_pendingLoot != null && (Object)(object)m_nview != (Object)null && m_nview.IsValid() && m_nview.IsOwner()) { m_nview.GetZDO().Set("hamud_loot", s_pendingLoot); m_nview.GetZDO().Set("hamud_level", s_pendingLevel); } } private void Start() { m_model = ((Component)this).transform.Find("HamudModel"); HamudVisual.HideVanillaRenderers(((Component)this).gameObject, m_model); m_sack = ((IEnumerable<Transform>)((Component)m_model).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "Sack")); Animation component = ((Component)m_model).GetComponent<Animation>(); component["death"].wrapMode = (WrapMode)8; component.Play("death"); m_start = Time.time; } private void Update() { if (!m_burst && !(Time.time - m_start < 1.2f)) { m_burst = true; Burst(); } } private Vector3 SackPoint() { //IL_004a: 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) //IL_001f: 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_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) //IL_004f: 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) //IL_0062: 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) Vector3 val = (((Object)(object)m_sack != (Object)null) ? m_sack.position : (((Component)this).transform.position + ((Component)this).transform.rotation * new Vector3(0f, 0.2f, -0.7f))); float num = default(float); if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetSolidHeight(val, ref num, 1000) && val.y < num + 0.15f) { val.y = num + 0.15f; } return val; } private void Burst() { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_00de: Unknown result type (might be due to invalid IL or missing references) Vector3 val = SackPoint(); HamudSounds.Play(Plugin.PopSfx, val); ZNetView.m_forceDisableInit = true; try { if ((Object)(object)Plugin.PuffVfx != (Object)null) { Object.Instantiate<GameObject>(Plugin.PuffVfx, val, Quaternion.identity); } if ((Object)(object)Plugin.CoinSfx != (Object)null) { Object.Instantiate<GameObject>(Plugin.CoinSfx, val, Quaternion.identity); } } finally { ZNetView.m_forceDisableInit = false; } GameObject val2 = new GameObject("HamudFlash"); val2.transform.position = val + Vector3.up * 0.4f; val2.AddComponent<HamudFlash>(); if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid() && m_nview.IsOwner()) { ZDO zDO = m_nview.GetZDO(); if (!zDO.GetBool("hamud_burst", false)) { zDO.Set("hamud_burst", true); DropLoot(val, zDO); } } } private static void Fling(ItemDrop drop, float speed) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0060: Unknown result type (might be due to invalid IL or missing references) Rigidbody val = (((Object)(object)drop != (Object)null) ? ((Component)drop).GetComponent<Rigidbody>() : null); if (!((Object)(object)val == (Object)null)) { Vector2 insideUnitCircle = Random.insideUnitCircle; Vector2 normalized = ((Vector2)(ref insideUnitCircle)).normalized; val.linearVelocity = new Vector3(normalized.x * speed, Random.Range(3.5f, 6f), normalized.y * speed); val.angularVelocity = Random.insideUnitSphere * 8f; } } private void DropLoot(Vector3 p, ZDO zdo) { //IL_004e: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_017b: 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_0131: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) Inventory obj = HamudThief.ParseLoot(zdo.GetString("hamud_loot", "")); int num = 0; foreach (ItemData allItem in obj.GetAllItems()) { if (!((Object)(object)allItem.m_dropPrefab == (Object)null)) { allItem.m_equipped = false; Fling(ItemDrop.DropItem(allItem, allItem.m_stack, p + Vector3.up * 0.3f, Random.rotation), Random.Range(1.2f, 2.5f)); num++; } } int num2 = Mathf.Max(1, zdo.GetInt("hamud_level", 1)); int num3 = Random.Range(Plugin.CoinsMin.Value, Plugin.CoinsMax.Value + 1) * num2; ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab("Coins") : null); int num4 = 0; if ((Object)(object)val != (Object)null && num3 > 0) { ItemData val2 = val.GetComponent<ItemDrop>().m_itemData.Clone(); val2.m_dropPrefab = val; int num5 = num3; while (num5 > 0) { int num6 = Mathf.Min(num5, Random.Range(2, 6)); num5 -= num6; Fling(ItemDrop.DropItem(val2, num6, p + Vector3.up * 0.3f, Random.rotation), Random.Range(1.5f, 3.2f)); num4++; } } HamudThief.Debug($"BURST at {p}: {num} stolen stacks, {num3} coins in {num4} piles (level {num2})"); } } public class HamudFlash : MonoBehaviour { private Light m_light; private float m_t; private void Awake() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) m_light = ((Component)this).gameObject.AddComponent<Light>(); m_light.type = (LightType)2; m_light.color = new Color(1f, 0.75f, 0.3f); m_light.range = 6f; m_light.intensity = 3f; } private void Update() { m_t += Time.deltaTime; m_light.intensity = Mathf.Lerp(3f, 0f, m_t / 0.35f); if (m_t > 0.4f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] public static class HamudStealPatch { private static void Prefix(Character __instance, HitData hit) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer || ((Character)val).IsDead() || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsOwner()) { return; } Character attacker = hit.GetAttacker(); HamudThief hamudThief = (((Object)(object)attacker != (Object)null) ? ((Component)attacker).GetComponent<HamudThief>() : null); if ((Object)(object)hamudThief == (Object)null) { return; } HamudThief.Debug($"grab hit {val.GetPlayerName()}: canSteal={hamudThief.CanSteal} loot={hamudThief.LootCount}"); if (hamudThief.CanSteal) { if (hit.m_blockable && ((Character)val).IsBlocking()) { HamudThief.Debug("grab blocked"); } else if (hit.m_dodgeable && ((Character)val).IsDodgeInvincible()) { HamudThief.Debug("grab dodged"); } else { HamudThief.StealFrom(val, hamudThief); } } } } [HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[] { typeof(Character), typeof(Character) })] public static class HamudHostilityPatch { private static void Postfix(Character a, Character b, ref bool __result) { if ((Object)(object)a == (Object)null || (Object)(object)b == (Object)null) { return; } bool flag = (Object)(object)((Component)a).GetComponent<HamudThief>() != (Object)null; bool flag2 = (Object)(object)((Component)b).GetComponent<HamudThief>() != (Object)null; if (flag || flag2) { if (flag && flag2) { __result = false; } else { __result = (flag ? ((Component)a).GetComponent<HamudThief>().WantsTarget(b) : a.IsPlayer()); } } } } [HarmonyPatch(typeof(Player), "Update")] public static class HamudStealableFlagPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { HamudThief.UpdateStealableFlag(__instance); } } } [HarmonyPatch(typeof(Character), "OnDeath")] public static class HamudDeathPatch { private static void Prefix(Character __instance) { HamudThief component = ((Component)__instance).GetComponent<HamudThief>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsOwner()) { HamudCorpse.s_pendingLoot = component.LootString; HamudCorpse.s_pendingLevel = __instance.GetLevel(); } } private static void Finalizer() { HamudCorpse.s_pendingLoot = null; HamudCorpse.s_pendingLevel = 1; } } [BepInPlugin("wleee.hamudhabob", "Hamud Habob", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "wleee.hamudhabob"; public const string Version = "1.0.0"; public const string PrefabName = "HamudHabob"; internal static ManualLogSource Log; internal static Plugin Instance; internal static ConfigEntry<string> BaseCreature; internal static ConfigEntry<float> ModelScale; internal static ConfigEntry<float> ModelYaw; internal static ConfigEntry<float> Health; internal static ConfigEntry<float> StealDamage; internal static ConfigEntry<float> RunSpeed; internal static ConfigEntry<float> WalkSpeed; internal static ConfigEntry<float> FleeSeconds; internal static ConfigEntry<int> MaxLoot; internal static ConfigEntry<bool> StealFromHotbar; internal static ConfigEntry<bool> StealEquipped; internal static ConfigEntry<int> CoinsMin; internal static ConfigEntry<int> CoinsMax; internal static ConfigEntry<string> SpawnBiomes; internal static ConfigEntry<bool> SpawnEnabled; internal static ConfigEntry<float> SpawnChance; internal static ConfigEntry<float> SpawnInterval; internal static ConfigEntry<int> MaxSpawned; internal static ConfigEntry<int> MaxLevel; internal static ConfigEntry<bool> SpawnAtNight; internal static ConfigEntry<float> SnatchRange; internal static ConfigEntry<float> NoticeRange; internal static ConfigEntry<bool> VoiceEnabled; internal static ConfigEntry<float> VoiceVolume; internal static ConfigEntry<float> IdleVoiceInterval; internal static ConfigEntry<float> IdleVoiceChance; internal static ConfigEntry<float> CorpseSeconds; internal static ConfigEntry<float> WalkStride; internal static ConfigEntry<float> RunStride; internal static GlbModel Model; internal static Material ModelMaterial; internal static GameObject VoiceSfx; internal static GameObject LaughSfx; internal static GameObject PopSfx; internal static GameObject PuffVfx; internal static GameObject CoinSfx; private void Awake() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Instance = this; BindConfig(); string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); GameObject val = new GameObject("Hamud_Templates"); val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); Model = GlbLoader.Load(Path.Combine(directoryName, "hamud.glb"), val.transform); Animation val2 = Model.Root.AddComponent<Animation>(); val2.playAutomatically = false; val2.cullingType = (AnimationCullingType)0; foreach (KeyValuePair<string, AnimationClip> clip in Model.Clips) { clip.Value.wrapMode = (WrapMode)(HamudVisual.LoopingClips.Contains(clip.Key) ? 2 : 8); val2.AddClip(clip.Value, clip.Key); } Log.LogInfo((object)($"Loaded model: {((Bounds)(ref Model.MeshBounds)).size} bind-pose size, {Model.Renderer.sharedMesh.vertexCount} verts, " + string.Format("emission={0}, anims [{1}]", (Object)(object)Model.Emission != (Object)null, string.Join(", ", Model.Clips.Keys)))); HamudSounds.Load(directoryName); AddLocalization(); Harmony val3 = new Harmony("wleee.hamudhabob"); val3.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)("Harmony patches: " + string.Join(", ", from m in val3.GetPatchedMethods() select m.DeclaringType?.Name + "." + m.Name))); CreatureManager.OnVanillaCreaturesAvailable += CreateHamud; } private void BindConfig() { BaseCreature = ((BaseUnityPlugin)this).Config.Bind<string>("Model", "BaseCreature", "Greyling", "Vanilla creature whose AI, attack and collider Hamud reuses (its model is hidden)."); ModelScale = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "Scale", 1f, "Model scale (1 = about 1.35 m with the cap)."); ModelYaw = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "ModelYaw", 0f, "Extra rotation of the model around the vertical axis, degrees."); WalkStride = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "WalkStride", 1.2f, "Speed (m/s) at which the sneak animation plays at 1x."); RunStride = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "RunStride", 4f, "Speed (m/s) at which the run animation plays at 1x."); CorpseSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Model", "CorpseSeconds", 5f, "How long the fallen Hamud stays before disappearing."); Health = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "Health", 25f, "Base health (a Surtling has 20): easy to kill, so you can get your stuff back."); StealDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "StealDamage", 4f, "Damage of the grab. The point of the grab is the theft, not the damage."); RunSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "RunSpeed", 6.5f, "Running speed, m/s (a sprinting player is about 7)."); WalkSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "WalkSpeed", 1.6f, "Sneaking speed, m/s."); FleeSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Theft", "FleeSeconds", 18f, "How long Hamud runs away after a successful theft."); MaxLoot = ((BaseUnityPlugin)this).Config.Bind<int>("Theft", "MaxLoot", 5, "Stolen stacks the sack holds. A full Hamud only runs from players."); StealFromHotbar = ((BaseUnityPlugin)this).Config.Bind<bool>("Theft", "StealFromHotbar", true, "Allow stealing from the hotbar (top inventory row)."); StealEquipped = ((BaseUnityPlugin)this).Config.Bind<bool>("Theft", "StealEquipped", true, "Allow stealing equipped items (he pulls them off you)."); CoinsMin = ((BaseUnityPlugin)this).Config.Bind<int>("Drops", "CoinsMin", 8, "Minimum coins that burst out of the sack (per star level)."); CoinsMax = ((BaseUnityPlugin)this).Config.Bind<int>("Drops", "CoinsMax", 25, "Maximum coins that burst out of the sack (per star level)."); SpawnEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn", "Enabled", true, "Spawn Hamud naturally."); SpawnBiomes = ((BaseUnityPlugin)this).Config.Bind<string>("Spawn", "Biomes", "Meadows, BlackForest, Swamp, Mountain, Plains, Mistlands, AshLands, DeepNorth", "Comma separated biomes he spawns in: Meadows, BlackForest, Swamp, Mountain, Plains, Mistlands, AshLands, DeepNorth."); SpawnChance = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "SpawnChance", 15f, "Chance in percent per spawn interval."); SpawnInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Spawn", "SpawnInterval", 400f, "Seconds between spawn attempts per spawner zone."); MaxSpawned = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn", "MaxSpawned", 1, "Max Hamuds alive near a player from this spawner."); MaxLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn", "MaxLevel", 3, "Max level (1 = no stars, 3 = two stars)."); SpawnAtNight = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn", "SpawnAtNight", true, "Also spawn at night."); SnatchRange = ((BaseUnityPlugin)this).Config.Bind<float>("Theft", "SnatchRange", 1.7f, "How close (m) Hamud has to get to snatch an item on the run."); NoticeRange = ((BaseUnityPlugin)this).Config.Bind<float>("Theft", "NoticeRange", 50f, "Hamud spots players with something to steal within this range (m), if nothing blocks the view."); VoiceEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Sound", "VoiceEnabled", true, "Hamud shouts his name and giggles. The sack pop always plays."); VoiceVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Sound", "Volume", 1f, "Volume of Hamud's voice and laugh (0-1)."); IdleVoiceInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Sound", "IdleVoiceInterval", 8f, "Seconds between random idle mutters."); IdleVoiceChance = ((BaseUnityPlugin)this).Config.Bind<float>("Sound", "IdleVoiceChance", 0.3f, "Chance (0-1) of an idle mutter each interval."); } private static void AddLocalization() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "enemy_hamudhabob", "Hamud Habob" }, { "hamud_stole", "Hamud Habob stole: {0} x{1}!" }, { "hamud_grab", "Hamud's grabby hand" } }); text = "Russian"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "enemy_hamudhabob", "Хамуд Хабоб" }, { "hamud_stole", "Хамуд Хабоб украл: {0} x{1}!" }, { "hamud_grab", "Загребущая рука Хамуда" } }); } private void CreateHamud() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_008f: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown CreatureManager.OnVanillaCreaturesAvailable -= CreateHamud; try { CreatureConfig val = new CreatureConfig { Name = "$enemy_hamudhabob" }; if (SpawnEnabled.Value) { Biome val2 = ParseBiomes(SpawnBiomes.Value); if ((int)val2 != 0) { val.AddSpawnConfig(new SpawnConfig { Name = "HamudHabob_spawn", Biome = val2, SpawnChance = SpawnChance.Value, SpawnInterval = SpawnInterval.Value, MaxSpawned = MaxSpawned.Value, MinGroupSize = 1, MaxGroupSize = 1, MinLevel = 1, MaxLevel = MaxLevel.Value, SpawnAtDay = true, SpawnAtNight = SpawnAtNight.Value, GroundOffset = 0.5f, MinAltitude = 1f, MaxAltitude = 1000f }); } } CustomCreature val3 = new CustomCreature("HamudHabob", BaseCreature.Value, val); GameObject prefab = val3.Prefab; SetupCharacter(prefab); SetupModel(prefab); SetupSounds(prefab); SetupWeapons(prefab); SetupDeath(prefab); PuffVfx = new string[2] { "vfx_coin_pile_destroyed", "vfx_coin_stack_destroyed" }.Select((string n) => PrefabManager.Instance.GetPrefab(n)).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => (Object)(object)p != (Object)null)); CoinSfx = PrefabManager.Instance.GetPrefab("sfx_coins_pile_destroyed"); prefab.AddComponent<HamudThief>(); prefab.AddComponent<HamudVisual>(); CreatureManager.Instance.AddCreature(val3); Log.LogInfo((object)("Registered HamudHabob (base " + BaseCreature.Value + "), puff vfx: " + (Object.op_Implicit((Object)(object)PuffVfx) ? ((Object)PuffVfx).name : "none"))); } catch (Exception ex) { Log.LogError((object)("Failed to create Hamud Habob: " + ex)); } } private static Biome ParseBiomes(string list) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) Biome val = (Biome)0; foreach (string item in from s in list.Split(',') select s.Trim() into s where s.Length > 0 select s) { if (Enum.TryParse<Biome>(item, ignoreCase: true, out Biome result)) { val |= result; } else { Log.LogWarning((object)("Unknown biome in config: " + item)); } } return val; } private static void SetupCharacter(GameObject prefab) { //IL_01e1: Unknown result type (might be due to invalid IL or missing references) Character component = prefab.GetComponent<Character>(); component.m_name = "$enemy_hamudhabob"; component.m_health = Health.Value; component.m_defeatSetGlobalKey = ""; component.m_runSpeed = RunSpeed.Value; component.m_walkSpeed = WalkSpeed.Value; component.m_speed = WalkSpeed.Value; Log.LogInfo((object)$"Base turn speed {component.m_turnSpeed}/{component.m_runTurnSpeed}"); component.m_turnSpeed = 720f; component.m_runTurnSpeed = 720f; CharacterDrop component2 = prefab.GetComponent<CharacterDrop>(); if ((Object)(object)component2 != (Object)null) { component2.m_drops = new List<Drop>(); } MonsterAI component3 = prefab.GetComponent<MonsterAI>(); if ((Object)(object)component3 != (Object)null) { component3.m_fleeIfLowHealth = 0f; component3.m_fleeIfHurtWhenTargetCantBeReached = true; component3.m_circleTargetInterval = 0f; component3.m_enableHuntPlayer = false; Log.LogInfo((object)$"Base senses: view {((BaseAI)component3).m_viewRange}m/{((BaseAI)component3).m_viewAngle}deg, hear {((BaseAI)component3).m_hearRange}m, alert {component3.m_alertRange}m"); ((BaseAI)component3).m_viewRange = Mathf.Max(((BaseAI)component3).m_viewRange, 30f); ((BaseAI)component3).m_viewAngle = Mathf.Max(((BaseAI)component3).m_viewAngle, 120f); ((BaseAI)component3).m_hearRange = Mathf.Max(((BaseAI)component3).m_hearRange, 25f); component3.m_alertRange = Mathf.Max(component3.m_alertRange, 15f); ((BaseAI)component3).m_smoothMovement = true; ((BaseAI)component3).m_moveMinAngle = 25f; } ManualLogSource log = Log; string text = $"Character: hp={component.m_health} run={component.m_runSpeed} walk={component.m_walkSpeed} "; object arg = component.m_faction; CapsuleCollider component4 = prefab.GetComponent<CapsuleCollider>(); log.LogInfo((object)(text + $"faction={arg} collider={((component4 != null) ? new float?(component4.height) : ((float?)null))}")); } private static Material CreateMaterial(GameObject basePrefab) { //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) SkinnedMeshRenderer val = ((IEnumerable<SkinnedMeshRenderer>)basePrefab.GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => (Object)(object)((Renderer)r).sharedMaterial != (Object)null)); Material val2; if ((Object)(object)val != (Object)null) { val2 = new Material(((Renderer)val).sharedMaterial); Log.LogInfo((object)("Base material shader '" + ((Object)val2.shader).name + "', textures [" + string.Join(", ", val2.GetTexturePropertyNames()) + "], keywords [" + string.Join(", ", val2.shaderKeywords) + "]")); string[] texturePropertyNames = val2.GetTexturePropertyNames(); foreach (string text in texturePropertyNames) { if (text != "_MainTex") { val2.SetTexture(text, (Texture)null); } } texturePropertyNames = val2.shaderKeywords; foreach (string text2 in texturePropertyNames) { val2.DisableKeyword(text2); } if (val2.HasProperty("_Glossiness")) { val2.SetFloat("_Glossiness", 0.1f); } if (val2.HasProperty("_Metallic")) { val2.SetFloat("_Metallic", 0f); } if (val2.HasProperty("_NoiseGlowEnabled")) { val2.SetFloat("_NoiseGlowEnabled", 0f); } } else { val2 = new Material(Shader.Find("Standard")); } ((Object)val2).name = "Hamud_mat"; val2.mainTexture = (Texture)(object)Model.Texture; val2.color = Color.white; if ((Object)(object)Model.Emission != (Object)null && val2.HasProperty("_EmissionMap")) { val2.SetTexture("_EmissionMap", (Texture)(object)Model.Emission); val2.SetColor("_EmissionColor", Model.EmissionColor); val2.EnableKeyword("_EMISSION"); val2.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1; } else if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", Color.black); } Log.LogInfo((object)("Hamud material: emission=" + (val2.HasProperty("_EmissionColor") ? ((object)val2.GetColor("_EmissionColor")/*cast due to .constrained prefix*/).ToString() : "n/a") + " keywords=[" + string.Join(", ", val2.shaderKeywords) + "]")); return val2; } internal static GameObject AttachModel(GameObject parent) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0085: 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_00a7: 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) ((Renderer)Model.Renderer).sharedMaterial = ModelMaterial; GameObject obj = Object.Instantiate<GameObject>(Model.Root, parent.transform, false); ((Object)obj).name = "HamudModel"; obj.transform.localPosition = Vector3.zero; obj.transform.localRotation = Quaternion.Euler(0f, ModelYaw.Value, 0f); Vector3 lossyScale = parent.transform.lossyScale; obj.transform.localScale = new Vector3(ModelScale.Value / lossyScale.x, ModelScale.Value / lossyScale.y, ModelScale.Value / lossyScale.z); return obj; } private static void SetupModel(GameObject prefab) { ModelMaterial = CreateMaterial(prefab); AttachModel(prefab); HamudVisual.HideVanillaRenderers(prefab, prefab.transform.Find("HamudModel")); } private static void SetupSounds(GameObject prefab) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown MonsterAI component = prefab.GetComponent<MonsterAI>(); GameObject val = FindSfx(((BaseAI)component).m_alertedEffects) ?? FindSfx(((BaseAI)component).m_idleSound) ?? FindSfx(prefab.GetComponent<Character>().m_hitEffects); if ((Object)(object)val == (Object)null) { Log.LogWarning((object)"No sfx template on the base creature, Hamud will be silent"); return; } PopSfx = HamudSounds.MakeSfx("sfx_hamud_pop", val, HamudSounds.Pop, "", throttle: false); Character component2 = prefab.GetComponent<Character>(); StripSfx(component2.m_hitEffects); StripSfx(component2.m_critHitEffects); StripSfx(component2.m_deathEffects); ((BaseAI)component).m_alertedEffects = new EffectList(); ((BaseAI)component).m_idleSound = new EffectList(); if (!VoiceEnabled.Value || HamudSounds.Voices.Length + HamudSounds.Laughs.Length == 0) { Log.LogInfo((object)"Voice disabled: Hamud is silent apart from the sack pop"); return; } VoiceSfx = HamudSounds.MakeSfx("sfx_hamud_voice", val, (HamudSounds.Voices.Length != 0) ? HamudSounds.Voices : HamudSounds.Laughs, "$enemy_hamudhabob"); LaughSfx = HamudSounds.MakeSfx("sfx_hamud_laugh", val, HamudSounds.Laughs, "$enemy_hamudhabob"); GameObject sfx = HamudSounds.MakeSfx("sfx_hamud_mutter", val, HamudSounds.Voices.Concat(HamudSounds.Laughs).ToArray(), "$enemy_hamudhabob"); ((BaseAI)component).m_alertedEffects = Effect(VoiceSfx); ((BaseAI)component).m_idleSound = Effect(sfx); ((BaseAI)component).m_idleSoundInterval = IdleVoiceInterval.Value; ((BaseAI)component).m_idleSoundChance = IdleVoiceChance.Value; Log.LogInfo((object)("Sounds cloned from '" + ((Object)val).name + "'")); static EffectList Effect(GameObject prefab2) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_000f: 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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown EffectList val2 = new EffectList(); val2.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { new EffectData { m_prefab = prefab2, m_enabled = true } }; return val2; } } internal static void StripSfx(EffectList list) { if (list?.m_effectPrefabs != null) { list.m_effectPrefabs = list.m_effectPrefabs.Where((EffectData e) => (Object)(object)e.m_prefab == (Object)null || (Object)(object)e.m_prefab.GetComponent<ZSFX>() == (Object)null).ToArray(); } } private static GameObject FindSfx(EffectList list) { return list?.m_effectPrefabs?.Select((EffectData e) => e.m_prefab).FirstOrDefault((Func<GameObject, bool>)((GameObject p) => (Object)(object)p != (Object)null && (Object)(object)p.GetComponent<ZSFX>() != (Object)null && (Object)(object)p.GetComponent<AudioSource>() != (Object)null)); } private static void SetupWeapons(GameObject prefab) { Humanoid component = prefab.GetComponent<Humanoid>(); if ((Object)(object)component == (Object)null) { return; } Dictionary<GameObject, GameObject> cache = new Dictionary<GameObject, GameObject>(); component.m_defaultItems = ConvertAll(component.m_defaultItems); component.m_randomWeapon = ConvertAll(component.m_randomWeapon); if (component.m_randomSets != null) { ItemSet[] randomSets = component.m_randomSets; foreach (ItemSet val in randomSets) { val.m_items = ConvertAll(val.m_items); } } if (component.m_randomItems != null) { RandomItem[] randomItems = component.m_randomItems; foreach (RandomItem val2 in randomItems) { val2.m_prefab = Convert(val2.m_prefab); } } GameObject Convert(GameObject item) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00ef: 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_0160: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Expected O, but got Unknown //IL_0214: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { return null; } if (cache.TryGetValue(item, out var value)) { return value; } ItemDrop component2 = item.GetComponent<ItemDrop>(); if ((Object)(object)component2 == (Object)null || !component2.m_itemData.IsWeapon()) { return cache[item] = item; } GameObject val4 = PrefabManager.Instance.CreateClonedPrefab("Hamud_" + ((Object)item).name, item); SharedData shared = val4.GetComponent<ItemDrop>().m_itemData.m_shared; shared.m_name = "$hamud_grab"; Renderer[] componentsInChildren = val4.GetComponentsInChildren<Renderer>(true); for (int j = 0; j < componentsInChildren.Length; j++) { Object.DestroyImmediate((Object)(object)componentsInChildren[j]); } MeshFilter[] componentsInChildren2 = val4.GetComponentsInChildren<MeshFilter>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[j]); } DamageTypes val5 = (shared.m_damages = new DamageTypes { m_blunt = StealDamage.Value }); shared.m_attackStatusEffect = null; shared.m_attackForce = 5f; Attack attack = shared.m_attack; Log.LogInfo((object)$"Base grab: range {attack.m_attackRange}, angle {attack.m_attackAngle}, ray {attack.m_attackRayWidth}, height {attack.m_attackHeight}, type {attack.m_attackType}"); attack.m_attackRange = Mathf.Max(attack.m_attackRange, 2.1f); attack.m_attackAngle = Mathf.Max(attack.m_attackAngle, 120f); attack.m_attackRayWidth = Mathf.Max(attack.m_attackRayWidth, 0.35f); StripSfx(shared.m_startEffect); StripSfx(shared.m_triggerEffect); StripSfx(shared.m_trailStartEffect); ItemManager.Instance.AddItem(new CustomItem(val4, false)); Log.LogInfo((object)$"Attack '{((Object)item).name}' -> '{((Object)val4).name}': blunt {val5.m_blunt}, range {shared.m_aiAttackRange}, interval {shared.m_aiAttackInterval}"); return cache[item] = val4; } GameObject[] ConvertAll(GameObject[] arr) { return arr?.Select(Convert).ToArray(); } } private static void SetupDeath(GameObject prefab) { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) EffectData[] array = prefab.GetComponent<Character>().m_deathEffects?.m_effectPrefabs; if (array == null) { return; } Log.LogInfo((object)("Base death effects: " + string.Join(", ", array.Select((EffectData e) => (!Object.op_Implicit((Object)(object)e.m_prefab)) ? "null" : ((Object)e.m_prefab).name)))); bool flag = false; foreach (EffectData item in array.OrderByDescending((EffectData e) => (Object)(object)e.m_prefab != (Object)null && (Object)(object)e.m_prefab.GetComponent<Ragdoll>() != (Object)null)) { if ((Object)(object)item.m_prefab == (Object)null || (Object)(object)item.m_prefab.GetComponent<ZSFX>() != (Object)null) { continue; } if (flag) { item.m_enabled = false; continue; } Ragdoll component = item.m_prefab.GetComponent<Ragdoll>(); GameObject val = PrefabManager.Instance.CreateClonedPrefab("HamudHabob_corpse", item.m_prefab); ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem obj in componentsInChildren) { EmissionModule emission = obj.emission; ((EmissionModule)(ref emission)).enabled = false; MainModule main = obj.main; ((MainModule)(ref main)).playOnAwake = false; } AttachModel(val); HamudVisual.HideVanillaRenderers(val, val.transform.Find("HamudModel")); val.AddComponent<HamudCorpse>(); Ragdoll component2 = val.GetComponent<Ragdoll>(); if ((Object)(object)component2 != (Object)null) { component2.m_dropItems = false; component2.m_ttl = Mathf.Max(component2.m_ttl, CorpseSeconds.Value); } else { TimedDestruction obj2 = val.GetComponent<TimedDestruction>() ?? val.AddComponent<TimedDestruction>(); obj2.m_timeout = CorpseSeconds.Value; obj2.m_triggerOnAwake = true; } PrefabManager.Instance.AddPrefab(val); Log.LogInfo((object)$"Corpse cloned from '{((Object)item.m_prefab).name}' (ragdoll: {(Object)(object)component != (Object)null}, networked: {(Object)(object)val.GetComponent<ZNetView>() != (Object)null})"); item.m_prefab = val; flag = true; } } } public static class WavLoader { public static AudioClip Load(string path) { byte[] array = File.ReadAllBytes(path); int num = 0; int num2 = 0; int num3 = 0; int num4 = -1; int num5 = 0; int num6; for (int i = 12; i + 8 <= array.Length; i += 8 + num6 + (num6 & 1)) { string text = Encoding.ASCII.GetString(array, i, 4); num6 = BitConverter.ToInt32(array, i + 4); if (text == "fmt ") { num = BitConverter.ToInt16(array, i + 10); num2 = BitConverter.ToInt32(array, i + 12); num3 = BitConverter.ToInt16(array, i + 22); } else if (text == "data") { num4 = i + 8; num5 = Math.Min(num6, array.Length - num4); break; } } if (num3 != 16 || num4 < 0 || num < 1) { throw new InvalidDataException(path + ": expected 16-bit PCM wav"); } int num7 = num5 / 2 / num; float[] array2 = new float[num7 * num]; for (int j = 0; j < array2.Length; j++) { array2[j] = (float)BitConverter.ToInt16(array, num4 + j * 2) / 32768f; } AudioClip obj = AudioClip.Create(Path.GetFileNameWithoutExtension(path), num7, num, num2, false); obj.SetData(array2, 0); return obj; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }