using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("KeyErrorFinn.Karambit")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+bc04d73ae4fad07de8140ae2c99315816af218cb")] [assembly: AssemblyProduct("How to Karambit")] [assembly: AssemblyTitle("KeyErrorFinn.Karambit")] [assembly: AssemblyVersion("1.1.0.0")] [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 KeyErrorFinn.Karambit { [HarmonyPatch(typeof(Item), "Awake")] internal static class ItemAwakePatch { private static void Postfix(Item __instance) { KarambitPlugin.Instance?.Replacer.TryReplace(__instance); } } [HarmonyPatch(typeof(Item), "OnPickUp")] internal static class ItemOnPickUpPatch { private static void Postfix(Item __instance) { KarambitPlugin.Instance?.Replacer.TryReplace(__instance); } } [HarmonyPatch(typeof(Item), "OnCurSkinChange")] internal static class ItemSkinPatch { private static void Postfix(Item __instance, byte next, bool asServer) { if (!asServer) { KarambitReplacer obj = KarambitPlugin.Instance?.Replacer; obj?.TryReplace(__instance); obj?.RefreshSkin(__instance, next); obj?.RefreshInventoryPreviews(__instance, next); } } } [HarmonyPatch(typeof(InventorySlot), "SetItem")] internal static class InventorySlotSetItemPatch { private static void Postfix(InventorySlot __instance, Item item) { KarambitPlugin.Instance?.Replacer.RefreshInventoryPreview(__instance, item, ((Object)(object)item != (Object)null) ? item.CurSkin : 0); } } [HarmonyPatch(typeof(InventorySlot), "ApplySkin")] internal static class InventorySlotApplySkinPatch { private static void Postfix(InventorySlot __instance, Item item) { KarambitPlugin.Instance?.Replacer.RefreshInventoryPreview(__instance, item, ((Object)(object)item != (Object)null) ? item.CurSkin : 0); } } internal sealed class KarambitInventoryPreview : MonoBehaviour { private const string PreviewName = "KeyErrorFinn Karambit Inventory Preview"; private GameObject _root; private KarambitModel _model; internal static KarambitInventoryPreview GetOrCreate(MeshFilter filter) { KarambitInventoryPreview component = ((Component)filter).GetComponent(); if (!((Object)(object)component != (Object)null)) { return ((Component)filter).gameObject.AddComponent(); } return component; } internal static void Clear(MeshFilter filter, Item item) { if ((Object)(object)filter == (Object)null) { return; } KarambitInventoryPreview component = ((Component)filter).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.RemovePreview(); if ((Object)(object)item != (Object)null) { filter.sharedMesh = item.Mesh; } } } internal KarambitModel Apply(Material sourceMaterial, bool useOriginalTexture, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset, Vector3 position, Vector3 rotation, float scale) { //IL_0054: 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_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_0026: Expected O, but got Unknown //IL_00a1: 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) if ((Object)(object)_root == (Object)null) { _root = new GameObject("KeyErrorFinn Karambit Inventory Preview") { hideFlags = (HideFlags)52 }; _root.transform.SetParent(((Component)this).transform, false); _root.layer = ((Component)this).gameObject.layer; } ApplyTransform(position, rotation, scale); if (_model == null) { _model = ObjKarambitModel.Create(_root.transform, sourceMaterial, useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset); } else { ObjKarambitModel.ApplyMaterialMode(_model.BladeRenderer, _model.HandleRenderer, sourceMaterial, useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset); } return _model; } internal void ApplyTransform(Vector3 position, Vector3 rotation, float scale) { //IL_001a: 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_002c: 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_0051: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null)) { _root.transform.localPosition = position; _root.transform.localRotation = Quaternion.Euler(rotation); _root.transform.localScale = Vector3.one * Mathf.Max(0.01f, scale); } } private void RemovePreview() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); Object.Destroy((Object)(object)_root); } _root = null; _model = null; } private void OnDestroy() { RemovePreview(); } } internal static class KarambitMeshFactory { internal static Mesh Create() { //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_0011: Expected O, but got Unknown //IL_005f: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh { name = "KeyErrorFinn Karambit Mesh" }; Combine(val, CreateCurvedBlade(), CreateBox(-0.075f, 0.03f, 0.075f, 0.32f, 0.075f), CreateTorus(0.085f, 0.022f, 20, 7, new Vector3(0f, 0.02f, 0f)), CreateBox(-0.105f, 0.285f, 0.105f, 0.335f, 0.075f)); val.RecalculateNormals(); val.RecalculateBounds(); Bounds bounds = val.bounds; Vector2[] array = (Vector2[])(object)new Vector2[val.vertexCount]; for (int i = 0; i < val.vertexCount; i++) { Vector3 val2 = val.vertices[i]; array[i] = new Vector2(Mathf.InverseLerp(((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.x, val2.x), Mathf.InverseLerp(((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.y, val2.y)); } val.uv = array; return val; } private static Mesh CreateCurvedBlade() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) //IL_003e: 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_0054: 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_006a: 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_0080: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: 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_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) Vector2[] array = (Vector2[])(object)new Vector2[7] { new Vector2(0f, 0.29f), new Vector2(0.2f, 0.4f), new Vector2(0.34f, 0.58f), new Vector2(0.32f, 0.77f), new Vector2(0.16f, 0.94f), new Vector2(-0.08f, 1.02f), new Vector2(-0.28f, 0.93f) }; Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length * 4]; List triangles = new List(); Vector2 val2 = default(Vector2); for (int i = 0; i < array.Length; i++) { Vector2 val = ((i == 0) ? (array[1] - array[0]) : ((i == array.Length - 1) ? (array[i] - array[i - 1]) : (array[i + 1] - array[i - 1]))); ((Vector2)(ref val)).Normalize(); ((Vector2)(ref val2))..ctor(0f - val.y, val.x); float num = Mathf.Lerp(1f, 0.12f, (float)i / (float)(array.Length - 1)); Vector2 val3 = array[i] + val2 * 0.055f * num; Vector2 val4 = array[i] - val2 * 0.055f * num; int num2 = i * 4; array2[num2] = new Vector3(val3.x, val3.y, -0.0175f); array2[num2 + 1] = new Vector3(val4.x, val4.y, -0.0175f); array2[num2 + 2] = new Vector3(val3.x, val3.y, 0.0175f); array2[num2 + 3] = new Vector3(val4.x, val4.y, 0.0175f); } for (int j = 0; j < array.Length - 1; j++) { int num3 = j * 4; int num4 = num3 + 4; AddQuad(triangles, num3, num4, num4 + 1, num3 + 1); AddQuad(triangles, num3 + 2, num3 + 3, num4 + 3, num4 + 2); AddQuad(triangles, num3, num3 + 2, num4 + 2, num4); AddQuad(triangles, num3 + 1, num4 + 1, num4 + 3, num3 + 3); } AddQuad(triangles, 0, 1, 3, 2); int num5 = (array.Length - 1) * 4; AddQuad(triangles, num5, num5 + 2, num5 + 3, num5 + 1); return Finish("Karambit Curved Blade", array2, triangles); } private static Mesh CreateBox(float xMin, float yMin, float xMax, float yMax, float depth) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) Vector3[] vertices = (Vector3[])(object)new Vector3[8] { new Vector3(xMin, yMin, (0f - depth) / 2f), new Vector3(xMax, yMin, (0f - depth) / 2f), new Vector3(xMax, yMax, (0f - depth) / 2f), new Vector3(xMin, yMax, (0f - depth) / 2f), new Vector3(xMin, yMin, depth / 2f), new Vector3(xMax, yMin, depth / 2f), new Vector3(xMax, yMax, depth / 2f), new Vector3(xMin, yMax, depth / 2f) }; List triangles = new List(); AddQuad(triangles, 0, 3, 2, 1); AddQuad(triangles, 4, 5, 6, 7); AddQuad(triangles, 0, 4, 7, 3); AddQuad(triangles, 1, 2, 6, 5); AddQuad(triangles, 3, 7, 6, 2); AddQuad(triangles, 0, 1, 5, 4); return Finish("Karambit Handle", vertices, triangles); } private static Mesh CreateTorus(float radius, float tube, int segments, int sides, Vector3 offset) { //IL_0049: 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_006b: Unknown result type (might be due to invalid IL or missing references) List list = new List(); List triangles = new List(); for (int i = 0; i < segments; i++) { float num = (float)i / (float)segments * (float)Math.PI * 2f; for (int j = 0; j < sides; j++) { float num2 = (float)j / (float)sides * (float)Math.PI * 2f; float num3 = radius + tube * Mathf.Cos(num2); list.Add(offset + new Vector3(Mathf.Cos(num) * num3, Mathf.Sin(num) * num3, tube * Mathf.Sin(num2))); } } for (int k = 0; k < segments; k++) { for (int l = 0; l < sides; l++) { int a = k * sides + l; int b = (k + 1) % segments * sides + l; int c = (k + 1) % segments * sides + (l + 1) % sides; int d = k * sides + (l + 1) % sides; AddQuad(triangles, a, b, c, d); } } return Finish("Karambit Finger Ring", list.ToArray(), triangles); } private static Mesh Finish(string name, Vector3[] vertices, List triangles) { //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_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_0027: 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) //IL_0034: Expected O, but got Unknown Mesh val = new Mesh { name = name, hideFlags = (HideFlags)52, vertices = vertices, triangles = triangles.ToArray() }; val.RecalculateNormals(); val.RecalculateBounds(); return val; } private static void AddQuad(List triangles, int a, int b, int c, int d) { triangles.Add(a); triangles.Add(b); triangles.Add(c); triangles.Add(a); triangles.Add(c); triangles.Add(d); } private static void Combine(Mesh destination, params Mesh[] parts) { //IL_0011: 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) CombineInstance[] array = (CombineInstance[])(object)new CombineInstance[parts.Length]; for (int i = 0; i < parts.Length; i++) { int num = i; CombineInstance val = default(CombineInstance); ((CombineInstance)(ref val)).mesh = parts[i]; array[num] = val; } destination.CombineMeshes(array, true, false); for (int j = 0; j < parts.Length; j++) { Object.Destroy((Object)(object)parts[j]); } } } [BepInPlugin("com.keyerrorfinn.karambit", "How to Karambit", "1.1.0")] public sealed class KarambitPlugin : BaseUnityPlugin { public const string PluginGuid = "com.keyerrorfinn.karambit"; public const string PluginName = "How to Karambit"; public const string PluginVersion = "1.1.0"; private ConfigEntry _enabled; private ConfigEntry _alternatePose; private ConfigEntry _menuToggleHotkey; private ConfigEntry _useOriginalTexture; private bool _showMenu; private static readonly MethodInfo UpdateInventoryCameraMethod = AccessTools.Method(typeof(PlayerInventory), "UpdateInventoryCamera", (Type[])null, (Type[])null); internal static KarambitPlugin Instance { get; private set; } internal KarambitReplacer Replacer { get; private set; } private void Awake() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) Instance = this; _enabled = ((BaseUnityPlugin)this).Config.Bind("Karambit", "Enabled", true, "Replace the held knife mesh with the karambit."); _alternatePose = ((BaseUnityPlugin)this).Config.Bind("Karambit", "Use alternate pose", false, "Use the alternate karambit grip pose."); _useOriginalTexture = ((BaseUnityPlugin)this).Config.Bind("Karambit", "Use original texture", false, "Use the model's original texture on the whole karambit instead of applying the selected knife skin to its blade and ring."); _menuToggleHotkey = ((BaseUnityPlugin)this).Config.Bind("Karambit", "Toggle menu hotkey", new KeyboardShortcut((KeyCode)291, Array.Empty()), "Open or close the karambit settings menu."); Replacer = new KarambitReplacer(((BaseUnityPlugin)this).Logger, _enabled, _alternatePose, _useOriginalTexture, ((BaseUnityPlugin)this).Config.Bind("Skin pattern", "UV scale", 1f, "Scale applied to the knife skin pattern."), ((BaseUnityPlugin)this).Config.Bind("Skin pattern", "UV rotation", -60f, "Rotation applied to the knife skin pattern."), ((BaseUnityPlugin)this).Config.Bind("Skin pattern", "UV offset", new Vector2(0.2f, 0.2f), "Offset applied to the knife skin pattern.")); new Harmony("com.keyerrorfinn.karambit").PatchAll(typeof(KarambitPlugin).Assembly); Replacer.ApplyMaterialMode(); Replacer.ApplyEnabledState(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"How to Karambit 1.1.0 loaded."); } private void Update() { //IL_0006: 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) KeyboardShortcut value = _menuToggleHotkey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _showMenu = !_showMenu; } if (_showMenu && (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305))) { if (Input.GetKeyDown((KeyCode)275)) { SetPose(!_alternatePose.Value, save: true); } else if (Input.GetKeyDown((KeyCode)276)) { SetMaterialMode(!_useOriginalTexture.Value, save: true); } else if (Input.GetKeyDown((KeyCode)274)) { SetEnabled(!_enabled.Value, save: true); } } } private void OnGUI() { if (_showMenu) { DrawSettingsMenu(); } } private void DrawSettingsMenu() { //IL_0022: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) float num = ((float)Screen.width - 360f) * 0.5f; GUI.Box(new Rect(num, 20f, 360f, 224f), "Karambit settings (F10 closes)"); GUI.Label(new Rect(num + 14f, 50f, 320f, 20f), "Pose: Ctrl+Right Arrow"); if (GUI.Button(new Rect(num + 14f, 74f, 150f, 28f), _alternatePose.Value ? "Blade Down" : "Blade Down ✓")) { SetPose(alternate: false, save: true); } if (GUI.Button(new Rect(num + 174f, 74f, 150f, 28f), _alternatePose.Value ? "Blade Up ✓" : "Blade Up")) { SetPose(alternate: true, save: true); } GUI.Label(new Rect(num + 14f, 110f, 320f, 20f), "Material: Ctrl+Left Arrow"); if (GUI.Button(new Rect(num + 14f, 134f, 150f, 28f), _useOriginalTexture.Value ? "Skins" : "Skins ✓")) { SetMaterialMode(useOriginalTexture: false, save: true); } if (GUI.Button(new Rect(num + 174f, 134f, 150f, 28f), _useOriginalTexture.Value ? "Model Default ✓" : "Model Default")) { SetMaterialMode(useOriginalTexture: true, save: true); } GUI.Label(new Rect(num + 14f, 170f, 320f, 20f), "Knife: Ctrl+Down Arrow"); if (GUI.Button(new Rect(num + 14f, 194f, 150f, 28f), _enabled.Value ? "Karambit ✓" : "Karambit")) { SetEnabled(enabled: true, save: true); } if (GUI.Button(new Rect(num + 174f, 194f, 150f, 28f), _enabled.Value ? "Default Knife" : "Default Knife ✓")) { SetEnabled(enabled: false, save: true); } } private void SetPose(bool alternate, bool save) { _alternatePose.Value = alternate; Replacer?.ApplyLiveTransform(); if (save) { ((BaseUnityPlugin)this).Config.Save(); } } private void SetMaterialMode(bool useOriginalTexture, bool save) { _useOriginalTexture.Value = useOriginalTexture; Replacer?.ApplyMaterialMode(); RefreshInventoryCamera(); ((BaseUnityPlugin)this).Logger.LogInfo((object)(useOriginalTexture ? "Karambit material: original model texture." : "Karambit material: original textured handle with selected knife skin on blade and ring.")); if (save) { ((BaseUnityPlugin)this).Config.Save(); } } private void SetEnabled(bool enabled, bool save) { _enabled.Value = enabled; Replacer?.ApplyEnabledState(); RefreshInventoryCamera(); ((BaseUnityPlugin)this).Logger.LogInfo((object)(enabled ? "Knife model: karambit." : "Knife model: game default.")); if (save) { ((BaseUnityPlugin)this).Config.Save(); } } private static void RefreshInventoryCamera() { if ((Object)(object)Player.LocalPlayer != (Object)null && (Object)(object)Player.LocalPlayer.Inventory != (Object)null) { UpdateInventoryCameraMethod?.Invoke(Player.LocalPlayer.Inventory, null); } } } internal sealed class KarambitReplacer { private const string ReplacementName = "KeyErrorFinn Karambit"; private static readonly MethodInfo ApplySkinToRendererMethod = AccessTools.Method(AccessTools.TypeByName("ShaderManager"), "ApplyItemSkin", new Type[3] { typeof(ItemSkin), typeof(Renderer), typeof(bool) }, (Type[])null); private static readonly FieldInfo InHandHolderField = AccessTools.Field(typeof(Item), "_inHandHolder"); private static readonly FieldInfo OutOfHandHolderField = AccessTools.Field(typeof(Item), "_outOfHandHolder"); private static readonly FieldInfo HandModelRightField = AccessTools.Field(typeof(Item), "_handModelRight"); private static readonly FieldInfo HandModelLeftField = AccessTools.Field(typeof(Item), "_handModelLeft"); private static readonly FieldInfo InventoryFilterField = AccessTools.Field(typeof(InventorySlot), "_filter"); private static readonly FieldInfo InventoryRendererField = AccessTools.Field(typeof(InventorySlot), "_renderer"); private readonly ManualLogSource _logger; private readonly ConfigEntry _enabled; private readonly ConfigEntry _alternatePose; private readonly ConfigEntry _useOriginalTexture; private readonly ConfigEntry _skinUvScale; private readonly ConfigEntry _skinUvRotation; private readonly ConfigEntry _skinUvOffset; private static readonly Vector3 BladeDownPosition = new Vector3(1.06f, -1.76f, 1.74f); private static readonly Vector3 BladeDownRotation = new Vector3(183.49f, -442.97f, 200f); private static readonly Vector3 BladeUpPosition = new Vector3(0.22f, 1.51f, 2.75f); private static readonly Vector3 BladeUpRotation = new Vector3(183.7f, -260.97f, 0f); private static readonly Vector3 InventoryPosition = new Vector3(0.87f, -0.05f, 0f); private static readonly Vector3 InventoryRotation = new Vector3(179f, 90f, -80f); private const float KarambitScale = 0.875f; private const float InventoryScale = 0.72f; private Vector3 CurrentPosition { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!_alternatePose.Value) { return BladeDownPosition; } return BladeUpPosition; } } private Vector3 CurrentRotation { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!_alternatePose.Value) { return BladeDownRotation; } return BladeUpRotation; } } internal KarambitReplacer(ManualLogSource logger, ConfigEntry enabled, ConfigEntry alternatePose, ConfigEntry useOriginalTexture, ConfigEntry skinUvScale, ConfigEntry skinUvRotation, ConfigEntry skinUvOffset) { _logger = logger; _enabled = enabled; _alternatePose = alternatePose; _useOriginalTexture = useOriginalTexture; _skinUvScale = skinUvScale; _skinUvRotation = skinUvRotation; _skinUvOffset = skinUvOffset; } internal void TryReplace(Item item) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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) //IL_00e5: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) if (!_enabled.Value || (Object)(object)item == (Object)null || !IsKnife(item)) { return; } if (HasReplacement(((Component)item).transform)) { RefreshExistingSkin(item); return; } Transform val = FindDeepChild(((Component)item).transform, "KnifeAnimated"); Transform val2 = (((Object)(object)val != (Object)null) ? FindDeepChild(val, "r_IK") : null); Transform val3 = (((Object)(object)val2 != (Object)null) ? FindDirectChild(val2, "Knife") : null); if ((Object)(object)val3 == (Object)null) { _logger.LogWarning((object)("Found knife item '" + ((Object)item).name + "', but could not find KnifeAnimated/r_IK/Knife.")); return; } SkinnedMeshRenderer val4 = FindVanillaKnifeRenderer(val); if ((Object)(object)val4 == (Object)null) { _logger.LogWarning((object)"Found the right knife bone, but no vanilla SkinnedMeshRenderer named Knife."); return; } GameObject val5 = new GameObject("KeyErrorFinn Karambit") { hideFlags = (HideFlags)52 }; val5.transform.SetParent(val3, false); val5.transform.localPosition = CurrentPosition; val5.transform.localRotation = Quaternion.Euler(CurrentRotation); val5.transform.localScale = Vector3.one * 25f * 0.875f; KarambitModel karambitModel = ObjKarambitModel.Create(val5.transform, ((Renderer)val4).material, _useOriginalTexture.Value, _skinUvScale.Value, _skinUvRotation.Value, _skinUvOffset.Value); SkinnedMeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (SkinnedMeshRenderer val6 in componentsInChildren) { if (string.Equals(((Object)((Component)val6).gameObject).name, "Knife", StringComparison.Ordinal)) { ((Renderer)val6).enabled = false; } } if (!_useOriginalTexture.Value) { ApplyCurrentSkin(item, karambitModel.BladeRenderer); } _logger.LogInfo((object)("Replaced knife mesh on '" + ((Object)item).name + "'. Blade shader: " + ((Object)karambitModel.BladeRenderer.material.shader).name + "; handle shader: " + ((Object)karambitModel.HandleRenderer.material.shader).name + ".")); } internal void ApplyLiveTransform() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) Transform[] array = Resources.FindObjectsOfTypeAll(); foreach (Transform val in array) { if (string.Equals(((Object)val).name, "KeyErrorFinn Karambit", StringComparison.Ordinal)) { val.localPosition = CurrentPosition; val.localRotation = Quaternion.Euler(CurrentRotation); val.localScale = Vector3.one * 25f * 0.875f; } } } internal void RefreshSkin(Item item, byte skinIndex) { //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_00b5: Unknown result type (might be due to invalid IL or missing references) if (_enabled.Value && !_useOriginalTexture.Value && !((Object)(object)item == (Object)null) && IsKnife(item)) { Transform obj = FindDeepChild(((Component)item).transform, "Karambit Blade"); Renderer val = ((obj != null) ? ((Component)obj).GetComponent() : null); if (!((Object)(object)val == (Object)null) && ApplySkin(item, skinIndex, val)) { ItemSkin val2 = item.SkinPreset.Skins[skinIndex]; _logger.LogInfo((object)$"Applied knife skin {skinIndex} '{((ItemSkin)(ref val2)).Name}' to karambit blade (UseSkin={((ItemSkin)(ref val2)).UseSkin}, Rainbow={((ItemSkin)(ref val2)).IsRainbowSkin}, Affects={((ItemSkin)(ref val2)).SkinAffects})."); } } } internal void ApplyMaterialMode() { Item[] array = Resources.FindObjectsOfTypeAll(); foreach (Item val in array) { if ((Object)(object)val != (Object)null && IsKnife(val) && HasReplacement(((Component)val).transform)) { ApplyMaterialMode(val); } } RefreshAllInventoryPreviews(); } internal void ApplyEnabledState() { Item[] array = Resources.FindObjectsOfTypeAll(); foreach (Item val in array) { if ((Object)(object)val == (Object)null || !IsKnife(val)) { continue; } Transform animated = FindDeepChild(((Component)val).transform, "KnifeAnimated"); Transform val2 = FindDeepChild(((Component)val).transform, "KeyErrorFinn Karambit"); if (_enabled.Value) { if ((Object)(object)val2 == (Object)null) { TryReplace(val); continue; } ((Component)val2).gameObject.SetActive(true); SetVanillaKnifeRenderers(animated, enabled: false); ApplyMaterialMode(val); } else { if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(false); } SetVanillaKnifeRenderers(animated, enabled: true); } } RefreshAllInventoryPreviews(); } internal void RefreshInventoryPreview(InventorySlot slot, Item item, int skinIndex) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)slot == (Object)null) { return; } object? obj = InventoryFilterField?.GetValue(slot); MeshFilter val = (MeshFilter)((obj is MeshFilter) ? obj : null); object? obj2 = InventoryRendererField?.GetValue(slot); Renderer val2 = (Renderer)((obj2 is Renderer) ? obj2 : null); if ((Object)(object)val == (Object)null) { return; } if (!_enabled.Value || (Object)(object)item == (Object)null || !IsKnife(item) || (Object)(object)val2 == (Object)null) { KarambitInventoryPreview.Clear(val, item); return; } KarambitModel karambitModel = KarambitInventoryPreview.GetOrCreate(val).Apply(val2.material, _useOriginalTexture.Value, _skinUvScale.Value, _skinUvRotation.Value, _skinUvOffset.Value, InventoryPosition, InventoryRotation, 0.72f); val.sharedMesh = null; if (!_useOriginalTexture.Value) { ApplySkin(item, skinIndex, karambitModel.BladeRenderer); } } internal void RefreshInventoryPreviews(Item item, int skinIndex) { if ((Object)(object)item == (Object)null || !IsKnife(item)) { return; } InventorySlot[] array = Resources.FindObjectsOfTypeAll(); foreach (InventorySlot val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val.Item == (Object)(object)item) { RefreshInventoryPreview(val, item, skinIndex); } } } internal void RefreshAllInventoryPreviews() { InventorySlot[] array = Resources.FindObjectsOfTypeAll(); foreach (InventorySlot val in array) { if ((Object)(object)val != (Object)null) { RefreshInventoryPreview(val, val.Item, ((Object)(object)val.Item != (Object)null) ? val.Item.CurSkin : 0); } } } private void ApplyMaterialMode(Item item) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) Transform val = FindDeepChild(((Component)item).transform, "KnifeAnimated"); SkinnedMeshRenderer val2 = (((Object)(object)val != (Object)null) ? FindVanillaKnifeRenderer(val) : null); Transform obj = FindDeepChild(((Component)item).transform, "Karambit Blade"); Renderer val3 = ((obj != null) ? ((Component)obj).GetComponent() : null); Transform obj2 = FindDeepChild(((Component)item).transform, "Karambit Handle"); Renderer val4 = ((obj2 != null) ? ((Component)obj2).GetComponent() : null); if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null)) { ObjKarambitModel.ApplyMaterialMode(val3, val4, ((Renderer)val2).material, _useOriginalTexture.Value, _skinUvScale.Value, _skinUvRotation.Value, _skinUvOffset.Value); if (!_useOriginalTexture.Value) { ApplyCurrentSkin(item, val3); } } } private static bool IsKnife(Item item) { if (!string.Equals(((Object)item).name, "Knife", StringComparison.OrdinalIgnoreCase)) { return string.Equals(item.GetName(), "Knife", StringComparison.OrdinalIgnoreCase); } return true; } private static Transform FindDirectChild(Transform parent, string name) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown foreach (Transform item in parent) { Transform val = item; if (string.Equals(((Object)val).name, name, StringComparison.Ordinal)) { return val; } } return null; } private static Transform FindDeepChild(Transform parent, string name) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if ((Object)(object)parent == (Object)null) { return null; } foreach (Transform item in parent) { Transform val = item; if (string.Equals(((Object)val).name, name, StringComparison.Ordinal)) { return val; } Transform val2 = FindDeepChild(val, name); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } private static bool HasReplacement(Transform root) { Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (string.Equals(((Object)componentsInChildren[i]).name, "KeyErrorFinn Karambit", StringComparison.Ordinal)) { return true; } } return false; } private static SkinnedMeshRenderer FindVanillaKnifeRenderer(Transform animated) { SkinnedMeshRenderer[] componentsInChildren = ((Component)animated).GetComponentsInChildren(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (string.Equals(((Object)((Component)val).gameObject).name, "Knife", StringComparison.Ordinal)) { return val; } } return null; } private static void SetVanillaKnifeRenderers(Transform animated, bool enabled) { if ((Object)(object)animated == (Object)null) { return; } SkinnedMeshRenderer[] componentsInChildren = ((Component)animated).GetComponentsInChildren(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (string.Equals(((Object)((Component)val).gameObject).name, "Knife", StringComparison.Ordinal)) { ((Renderer)val).enabled = enabled; } } } private static void ApplyCurrentSkin(Item item, Renderer bladeRenderer) { ApplySkin(item, item.CurSkin, bladeRenderer); } private static bool ApplySkin(Item item, int skinIndex, Renderer bladeRenderer) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) SkinPreset skinPreset = item.SkinPreset; IReadOnlyList readOnlyList = ((skinPreset != null) ? skinPreset.Skins : null); if (readOnlyList == null || skinIndex < 0 || skinIndex >= readOnlyList.Count || (Object)(object)bladeRenderer == (Object)null) { return false; } if ((Object)(object)bladeRenderer.sharedMaterial == (Object)null || !string.Equals(((Object)bladeRenderer.sharedMaterial.shader).name, "Shader Graphs/DefaultShader", StringComparison.Ordinal)) { return false; } ApplySkinToRendererMethod?.Invoke(null, new object[3] { readOnlyList[skinIndex], bladeRenderer, false }); return ApplySkinToRendererMethod != null; } private static void RefreshExistingSkin(Item item) { Transform obj = FindDeepChild(((Component)item).transform, "Karambit Blade"); Renderer val = ((obj != null) ? ((Component)obj).GetComponent() : null); if (!((Object)(object)val == (Object)null)) { ApplyCurrentSkin(item, val); } } } internal sealed class KarambitModel { internal Renderer BladeRenderer; internal Renderer HandleRenderer; } internal static class ObjKarambitModel { private static Texture2D _originalTexture; private static ObjData _objData; internal static KarambitModel Create(Transform parent, Material bladeMaterial, bool useOriginalTexture, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset) { //IL_0022: 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_0068: Unknown result type (might be due to invalid IL or missing references) ObjData objData = GetObjData(); KarambitModel karambitModel = new KarambitModel(); karambitModel.BladeRenderer = CreatePart("Karambit Blade", parent, objData.BladeTriangles, objData, null, !useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset); karambitModel.HandleRenderer = CreatePart("Karambit Handle", parent, objData.HandleTriangles, objData, null, useKnifeSkinUv: false, 1f, 0f, Vector2.zero); ApplyMaterialMode(karambitModel.BladeRenderer, karambitModel.HandleRenderer, bladeMaterial, useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset); return karambitModel; } internal static void ApplyMaterialMode(Renderer blade, Renderer handle, Material source, bool useOriginalTexture, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) RebuildBladeMesh(blade, !useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset); if (useOriginalTexture) { Material sharedMaterial = (blade.sharedMaterial = CreateOriginalTextureMaterial()); handle.sharedMaterial = sharedMaterial; } else { blade.sharedMaterial = CreateSkinnableBladeMaterial(source); handle.sharedMaterial = CreateOriginalTextureMaterial(); } } private static Material CreateSkinnableBladeMaterial(Material source) { //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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0042: Expected O, but got Unknown Material val = new Material(source) { name = "Karambit Blade Skin Material" }; Texture2D texture = CreateSolidTexture("Karambit Neutral Normal", new Color(0.5f, 0.5f, 1f, 1f)); SetTextureIfPresent(val, "_Normal_Map", (Texture)(object)texture); return val; } private static Material CreateOriginalTextureMaterial() { //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01a4: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("UI/Default"); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("Could not find a shader for the original karambit texture."); } if ((Object)(object)_originalTexture == (Object)null) { string path = ResolveAssetDirectory(); _originalTexture = new Texture2D(2, 2, (TextureFormat)4, false) { name = "Original Karambit Texture", hideFlags = (HideFlags)52, wrapMode = (TextureWrapMode)0, filterMode = (FilterMode)1 }; MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }, null); if (!(methodInfo != null) || !(bool)methodInfo.Invoke(null, new object[3] { _originalTexture, File.ReadAllBytes(Path.Combine(path, "karambit.png")), false })) { throw new InvalidDataException("Could not decode assets/karambit.png."); } } Material val2 = new Material(val) { name = "Original Karambit Material", color = Color.white, mainTexture = (Texture)(object)_originalTexture }; SetTextureIfPresent(val2, "_BaseMap", (Texture)(object)_originalTexture); SetTextureIfPresent(val2, "_MainTex", (Texture)(object)_originalTexture); SetColorIfPresent(val2, "_BaseColor", Color.white); SetColorIfPresent(val2, "_Color", Color.white); SetFloatIfPresent(val2, "_Metallic", 0.35f); SetFloatIfPresent(val2, "_Smoothness", 0.45f); return val2; } private static string ResolveAssetDirectory() { string location = Assembly.GetExecutingAssembly().Location; if (!string.IsNullOrEmpty(location)) { string text = Path.Combine(Path.GetDirectoryName(location), "assets"); if (File.Exists(Path.Combine(text, "karanbit.obj"))) { return text; } } string text2 = Path.Combine(Paths.BepInExRootPath, "scripts", "assets"); if (File.Exists(Path.Combine(text2, "karanbit.obj"))) { return text2; } string text3 = Path.Combine(Paths.PluginPath, "KeyErrorFinn-Karambit", "assets"); if (File.Exists(Path.Combine(text3, "karanbit.obj"))) { return text3; } throw new DirectoryNotFoundException("Could not find the Karambit assets directory."); } private static ObjData GetObjData() { return _objData ?? (_objData = ObjData.Load(Path.Combine(ResolveAssetDirectory(), "karanbit.obj"))); } internal static void RebuildBladeMesh(Renderer blade, bool useKnifeSkinUv, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) MeshFilter component = ((Component)blade).GetComponent(); if (!((Object)(object)component == (Object)null)) { ObjData objData = GetObjData(); Mesh sharedMesh = component.sharedMesh; component.sharedMesh = objData.BuildMesh("Karambit Blade", objData.BladeTriangles, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset); if ((Object)(object)sharedMesh != (Object)null) { Object.Destroy((Object)(object)sharedMesh); } } } private static Texture2D CreateSolidTexture(string name, Color color) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0049: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { name = name, hideFlags = (HideFlags)52, wrapMode = (TextureWrapMode)0, filterMode = (FilterMode)1 }; val.SetPixels((Color[])(object)new Color[4] { color, color, color, color }); val.Apply(false, true); return val; } private static void SetTextureIfPresent(Material material, string property, Texture texture) { if (material.HasProperty(property)) { material.SetTexture(property, texture); } } private static void SetFloatIfPresent(Material material, string property, float value) { if (material.HasProperty(property)) { material.SetFloat(property, value); } } private static void SetColorIfPresent(Material material, string property, Color value) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty(property)) { material.SetColor(property, value); } } private static Renderer CreatePart(string name, Transform parent, List triangles, ObjData data, Material material, bool useKnifeSkinUv, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset) { //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_000e: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name) { hideFlags = (HideFlags)52 }; val.transform.SetParent(parent, false); val.layer = ((Component)parent).gameObject.layer; val.AddComponent().sharedMesh = data.BuildMesh(name, triangles, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset); MeshRenderer obj = val.AddComponent(); ((Renderer)obj).sharedMaterial = material; return (Renderer)(object)obj; } } internal sealed class ObjData { internal readonly List Positions = new List(); internal readonly List Uvs = new List(); internal readonly List BladeTriangles = new List(); internal readonly List HandleTriangles = new List(); internal static ObjData Load(string path) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) ObjData objData = new ObjData(); bool flag = true; string[] array = File.ReadAllLines(path); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 0) { continue; } if (array2[0] == "v" && array2.Length >= 4) { objData.Positions.Add(new Vector3(Parse(array2[1]), Parse(array2[2]), Parse(array2[3]))); } else if (array2[0] == "vt" && array2.Length >= 3) { objData.Uvs.Add(new Vector2(Parse(array2[1]), Parse(array2[2]))); } else if (array2[0] == "usemtl" && array2.Length >= 2) { flag = string.Equals(array2[1], "blade", StringComparison.OrdinalIgnoreCase); } else if (array2[0] == "f" && array2.Length >= 4) { ObjIndex[] array3 = new ObjIndex[array2.Length - 1]; for (int j = 1; j < array2.Length; j++) { array3[j - 1] = ObjIndex.Parse(array2[j]); } for (int k = 1; k < array3.Length - 1; k++) { ObjTriangle item = new ObjTriangle(array3[0], array3[k], array3[k + 1]); (flag ? objData.BladeTriangles : objData.HandleTriangles).Add(item); } } } if (objData.BladeTriangles.Count == 0 || objData.HandleTriangles.Count == 0) { throw new InvalidDataException("The karambit OBJ must contain both blade and karambit material groups."); } return objData; } internal Mesh BuildMesh(string name, List triangles, bool useKnifeSkinUv, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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) //IL_0106: Expected O, but got Unknown Dictionary map = new Dictionary(); List vertices = new List(); List list = new List(); List list2 = new List(); List list3 = new List(); List list4 = new List(); List list5 = new List(); foreach (ObjTriangle triangle in triangles) { Add(triangle.A, map, vertices, list, list2, list3, list4, list5, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset); Add(triangle.B, map, vertices, list, list2, list3, list4, list5, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset); Add(triangle.C, map, vertices, list, list2, list3, list4, list5, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset); } Mesh val = new Mesh { name = name, hideFlags = (HideFlags)52 }; val.SetVertices(vertices); val.SetUVs(0, list); val.SetUVs(1, list2); val.SetUVs(2, list3); val.SetUVs(3, list4); val.SetTriangles(list5, 0); val.RecalculateNormals(); val.RecalculateBounds(); return val; } private void Add(ObjIndex source, Dictionary map, List vertices, List uv0, List uv1, List uv2, List uv3, List indices, bool useKnifeSkinUv, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0118: 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_0128: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) if (!map.TryGetValue(source, out var value)) { value = vertices.Count; map.Add(source, value); vertices.Add(Positions[source.Position - 1]); Vector2 val = ((source.Uv > 0) ? Uvs[source.Uv - 1] : Vector2.zero); if (useKnifeSkinUv) { uv0.Add(new Vector2(0.9858f, 0.6968f)); uv1.Add(new Vector2(0.9775f, 0.6334f)); uv2.Add(new Vector2(0.9858f, 0.5171f)); Vector2 val2 = TransformPatternUv(new Vector2(Mathf.InverseLerp(0.04f, 0.94f, val.x), Mathf.InverseLerp(0.09f, 0.8f, val.y)), skinUvScale, skinUvRotation, skinUvOffset); uv3.Add(new Vector2(Mathf.LerpUnclamped(0.45f, 0.54f, val2.x), Mathf.LerpUnclamped(0.55f, 0.85f, val2.y))); } else { uv0.Add(val); uv1.Add(val); uv2.Add(val); uv3.Add(val); } } indices.Add(value); } private static Vector2 TransformPatternUv(Vector2 uv, float scale, float rotationDegrees, Vector2 offset) { //IL_0000: 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) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0053: 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_006b: 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_0075: 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) Vector2 val = (uv - new Vector2(0.5f, 0.5f)) * Mathf.Max(0.01f, scale); float num = rotationDegrees * ((float)Math.PI / 180f); float num2 = Mathf.Cos(num); float num3 = Mathf.Sin(num); return new Vector2(val.x * num2 - val.y * num3, val.x * num3 + val.y * num2) + new Vector2(0.5f, 0.5f) + offset; } private static float Parse(string value) { return float.Parse(value, CultureInfo.InvariantCulture); } } internal struct ObjIndex : IEquatable { internal int Position; internal int Uv; internal static ObjIndex Parse(string value) { string[] array = value.Split(new char[1] { '/' }); return new ObjIndex { Position = int.Parse(array[0], CultureInfo.InvariantCulture), Uv = ((array.Length > 1 && array[1].Length > 0) ? int.Parse(array[1], CultureInfo.InvariantCulture) : 0) }; } public bool Equals(ObjIndex other) { if (Position == other.Position) { return Uv == other.Uv; } return false; } public override bool Equals(object obj) { if (obj is ObjIndex) { return Equals((ObjIndex)obj); } return false; } public override int GetHashCode() { return (Position * 397) ^ Uv; } } internal struct ObjTriangle { internal ObjIndex A; internal ObjIndex B; internal ObjIndex C; internal ObjTriangle(ObjIndex a, ObjIndex b, ObjIndex c) { A = a; B = b; C = c; } } }