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<KarambitInventoryPreview>();
if (!((Object)(object)component != (Object)null))
{
return ((Component)filter).gameObject.AddComponent<KarambitInventoryPreview>();
}
return component;
}
internal static void Clear(MeshFilter filter, Item item)
{
if ((Object)(object)filter == (Object)null)
{
return;
}
KarambitInventoryPreview component = ((Component)filter).GetComponent<KarambitInventoryPreview>();
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<int> triangles = new List<int>();
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<int> triangles = new List<int>();
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<Vector3> list = new List<Vector3>();
List<int> triangles = new List<int>();
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<int> 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<int> 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<bool> _enabled;
private ConfigEntry<bool> _alternatePose;
private ConfigEntry<KeyboardShortcut> _menuToggleHotkey;
private ConfigEntry<bool> _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<bool>("Karambit", "Enabled", true, "Replace the held knife mesh with the karambit.");
_alternatePose = ((BaseUnityPlugin)this).Config.Bind<bool>("Karambit", "Use alternate pose", false, "Use the alternate karambit grip pose.");
_useOriginalTexture = ((BaseUnityPlugin)this).Config.Bind<bool>("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<KeyboardShortcut>("Karambit", "Toggle menu hotkey", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), "Open or close the karambit settings menu.");
Replacer = new KarambitReplacer(((BaseUnityPlugin)this).Logger, _enabled, _alternatePose, _useOriginalTexture, ((BaseUnityPlugin)this).Config.Bind<float>("Skin pattern", "UV scale", 1f, "Scale applied to the knife skin pattern."), ((BaseUnityPlugin)this).Config.Bind<float>("Skin pattern", "UV rotation", -60f, "Rotation applied to the knife skin pattern."), ((BaseUnityPlugin)this).Config.Bind<Vector2>("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<bool> _enabled;
private readonly ConfigEntry<bool> _alternatePose;
private readonly ConfigEntry<bool> _useOriginalTexture;
private readonly ConfigEntry<float> _skinUvScale;
private readonly ConfigEntry<float> _skinUvRotation;
private readonly ConfigEntry<Vector2> _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<bool> enabled, ConfigEntry<bool> alternatePose, ConfigEntry<bool> useOriginalTexture, ConfigEntry<float> skinUvScale, ConfigEntry<float> skinUvRotation, ConfigEntry<Vector2> 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<SkinnedMeshRenderer>(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<Transform>();
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<Renderer>() : 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<Item>();
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<Item>();
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<InventorySlot>();
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<InventorySlot>();
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<Renderer>() : null);
Transform obj2 = FindDeepChild(((Component)item).transform, "Karambit Handle");
Renderer val4 = ((obj2 != null) ? ((Component)obj2).GetComponent<Renderer>() : 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<Transform>(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<SkinnedMeshRenderer>(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<SkinnedMeshRenderer>(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<ItemSkin> 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<Renderer>() : 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<MeshFilter>();
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<ObjTriangle> 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<MeshFilter>().sharedMesh = data.BuildMesh(name, triangles, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset);
MeshRenderer obj = val.AddComponent<MeshRenderer>();
((Renderer)obj).sharedMaterial = material;
return (Renderer)(object)obj;
}
}
internal sealed class ObjData
{
internal readonly List<Vector3> Positions = new List<Vector3>();
internal readonly List<Vector2> Uvs = new List<Vector2>();
internal readonly List<ObjTriangle> BladeTriangles = new List<ObjTriangle>();
internal readonly List<ObjTriangle> HandleTriangles = new List<ObjTriangle>();
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<ObjTriangle> 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<ObjIndex, int> map = new Dictionary<ObjIndex, int>();
List<Vector3> vertices = new List<Vector3>();
List<Vector2> list = new List<Vector2>();
List<Vector2> list2 = new List<Vector2>();
List<Vector2> list3 = new List<Vector2>();
List<Vector2> list4 = new List<Vector2>();
List<int> list5 = new List<int>();
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<ObjIndex, int> map, List<Vector3> vertices, List<Vector2> uv0, List<Vector2> uv1, List<Vector2> uv2, List<Vector2> uv3, List<int> 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<ObjIndex>
{
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;
}
}
}